当前位置:首页 » 编程软件 » ident编译原理

ident编译原理

发布时间: 2024-08-29 02:15:20

1. 简述一下编译器和链接器的作用

1、编译器:
编译器对源文件进行编译,就是把源文件中的文本形式存在的源代码翻译成机器语言形式的目标文件的过程,在这个过程中,编译器会进行一系列的语法检查。如果编译通过,就会把对应的CPP转换成OBJ文件。
2、链接器:
当链接器进行链接的时候,首先决定各个目标文件在最终可执行文件里的位置。然后访问所有目标文件的地址重定义表,对其中记录的地址进行重定向(加上一个偏移量,即该编译单元在可执行文件上的起始地址)。
然后遍历所有目标文件的未解决符号表,并且在所有的导出符号表里查找匹配的符号,并在未解决符号表中所记录的位置上填写实现地址。最后把所有的目标文件的内容写在各自的位置上,再作一些另的工作,就生成一个可执行文件。

2. socks5代理服务是什么意思 有什么做用

Socks5是一个实现SOCKS v5协议的代理服务器。作为一个代理服务器,socks5鉴别、授权、处理客户的网络请求。它为客户建立连接到客户所请求的主机。客户机试图连接到网络时,只需连接到socks5的daemon。
接着是认证,客户请求socks5激活网络连接。包括bind,connect,sendto,ping,traceroute。
Socks5是独立于应用层协议的,能应付不同的网络服务。包括telnet,ftp,finger,whois,gopher,WWW。
Socks5 daemon 支持两种授权方式:
Username/Password -- 参考socks5.passwd
Kerberos 5 -- 要求Kerberos libraries的支持。使用Kerberos 5(GSS-API) 的其它信息,请参考Kerberos 的man page。

Socks5的运行方式:
Standalone – default
Preforking - -p
Threaded - -t 如果你的操作系统支持POSIX threads 并且你configure socks5时加了—with-threads 参数。-t参数使socks5运行在threaded 模式。所有的操作系统都对线程数和每进程的打开文件描述符加于限制。
Through inetd - -i,通过inetd启动。
你可以通过一些配置文件、环境变量和参数控制socks5 daemon。请参考socks5.conf(5)文档。这个配置文件的优先级高于环境变量和参数。环境变量设置高于参数设置。

OPTIONS
多个参数用空格分开。
-b [host:port] | --bindintfc [host:port]
host:port 指定socks5运行的主机和端口号用于代替缺省的端口。忽略主机的话,socks5使用0.0.0.0做为主机值。
-d [val] | -- debug[val]
打开debug模式,设置debug值为val。如果忽略此值,socks5仅仅发送警告信息。val 的有效值是1,2,3。如果指定其它值,socks5认为是3。有效值的含义:
1 LOG_NOTICE 不报错
2 LOG_INFO 报告信息
3 LOG_DEBUG 报告用于debug 的信息。
-f | --foreground
前台运行。当运行在standalone模式时,阻止从parent shell分裂。--foreground 一般用于调试
-i | --inetd
通过inetd运行socks5。
-n val | --nchildren val
设置同时存在的最大子进程数为val。Socks5预设最大子进程数为64。使用这个参数降低预设值。你不能设置最大子进程数超过操作系统限制的值。当运行在线程模式时,
socks5忽略此值,在oneshot 模式和 inetd 模式下,此参数也没用。
-o | --oneshot
在前台处理一个请求,打开debug模式,输出到stderr,然后退出。用于调试。
-p | --prefork
preforking进程运行socks5。同时需要 –nchildren 参数控制已forked 的进程数。
-s | --stderr
纪录所有的输出到stderr代替syslog。主要用于debug 模式。
-t | --threaded
运行在线程模式。要求你的操作系统支持POSIX threads 并且编译socks5时加了—with-threads 参数。如果线程模式无效,socks5打印一个错误信息,转到standalone 模式。
-v | --version
打印一条信息(包括当前socks5版本号)到stderr。

ENVIRONMENT
环境变量控制socks5怎样执行。可以在环境或配置文件中设置它们。当环境和配置文件有冲突时,配置文件的优先级高。在配置文件中设置变量,使用如下的语法:
set variable [value]
SOCKS5_BINDINTFC host:port
host:port 指定socks5运行的主机和端口号,用于代替缺省的端口。忽略时,socks5用0.0.0.0作为主机值。
SOCKS5_CONFFILE filename
Filename 指定配置文件。在许多系统中,缺省是/etc/socks5.conf。在运行socks5之前,设置这个变量。如果有多个socks5 daemon运行,为每个daemon使用不同的配置文件。
SOCKS5_DEMAND_IDENT
当客户没有响应ident 请求时,认证失败。使用SOCKS5_DEMAND_IDENT确认每个连接有一个关联的用户名。
SOCKS_ENCRYPT
如果可能的话,请求下一个socks5进程加密数据。SOCKS5_ENCRYPT 仅仅在编译socks5时包括了GSS-API认证时,才有意义。
SOCKS5_FORCE_ENCRYPT
当认证方式支持加密时,强迫客户加密数据。
SOCKS5_IDENTFILE filename
Filename指定存储ident信息的文件名。在许多系统中,缺省是/tmp/socks5.ident。当有多个socks5 daemon运行时,SOCKS5_IDENTFILE非常有用。
SOCKS5_MAXCHILD val
val指定同时存在的最大子进程数。Socks5预设为64。可以降低预设置。不能超过64。Socks5运行在线程模式时,忽略此参数。当运行在oneshot或inetd模式时,此参数不发生作用。
SOCKS_NOIDENT
忽略ident请求。当客户机没有运行identd时,使用SOCKS5_NOIDENT将降低超时值。
SOCKS_NOINTCHK
请求下一个socks5进程执行没有完整检查的代理请求。只有在编译时加入GSS-API认证时,SOCKS5_NOINTCHK才发生作用。
SOCKS_NONETMASKCHECK
指示daemon忽略检查主机的子网掩码。缺省时,daemon检查掩码,如果在同一子网时,在检查配置文件之前,直接连接。
SOCKS5_REVERSEMAP
总是试图影射地址到主机名。缺省时,socks5只有当主机名或域名在配置文件中使用时才影射。设置后,log文件将纪录主机名,这将降低性能。
SOCKS5_SERVICENAME
总是影射端口号到服务名。缺省时,socks5只有当服务名在配置文件中使用时才影射。设置后,log文件将纪录服务名,这将降低性能。
SOCKS5_PASSWD [password]
当socks5 daemon连接到其它socks服务器时,如果采用Username/Password 认证,用它来指定密码。
SOCKS5_PIDFILE filename
指定存储socks5进程ID的文件名。Socks5缺省存贮PID在/tmp/socks5.pid。你可以用—bindintfc参数或设置SOCKS5_BINDINTFC环境变量运行socks5在不同于缺省端口的其它端口。当运行在不同于缺省端口的其它端口时,socks5存贮PID在/tmp/socks5.pid-port。
SOCKS5_PWDFILE filename
指定密码文件。在许多系统中,缺省是/etc/socks5.passwd。
SOCKS5_TIMEOUT minutes
指定连接停顿最长时间。超过最大值后,socks5断开连接。忽略此值时,缺省是15。
SOCKS5_UDPPORTRANGE port1-port2
指定一个Socks5用来发送UDP包的UDP端口范围。
SOCKS5_USER [user id]
当socks5 daemon连接到其它socks server时,如果采用Username/Password认证,用此变量指定用户名。
SOCKS5_V4SUPPORT
缺省时,socks5只接受SOCKS V5协议(rfc 1928)的请求。设此变量后,socks5将接受SOCKS V4 协议的请求。
REQUEST FOR COMMENTS
RFC1928 SOCKS protocol Version 5
RFC1929 Username/Password Authentication for SOCKS V5
RFC1961 GSS-API Authentication Method for SOCKS Version 5
SEE ALSO
Socks5.conf(5)

3. pl0怎么扩展++,--功能

那我给你网站吧,我找很久了.那个东西是很需要的
http://download.csdn.net/source/191218
PL/0语言是Pascal语言的一个子集,这里分析的PL/0的编译程序包括了对PL/0语
言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。
PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。词法分析和代码生成作为独立的子程序供语法分析程序调用。语法分析的同时,提供了出错报告和出错恢复的功能。在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。
2.各功能模块描述

词法分析子程序分析:
词法分析子程序名为GETSYM,功能是从源程序中读出一个单词符号(TOTAKEN),把它的信息放入全局变量 SYM、ID和NUM中,字符变量放入CH中,语法分析器需要单词时,直接从这三个变量中获得。Getch过程通过反复调用Getch子过程从源程序过获取字符,并把它们拼成单词。GETCH过程中使用了行缓冲区技术以提高程序运行效率。
词法分析器的分析过程:调用GETSYM时,它通过GETCH过程从源程序中获得一个字符。如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到为保留字,则把SYM变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把SYM置为IDENT,把这个单词存入ID变量。查保留字表时使用了二分法查找以提高效率。如果Getch获得的字符是数字,则继续用Getch获取数字,并把它们拼成一个整数或实数,然后把SYM置为 INTEGER或REAL,并把拼成的数值放入NUM变量。如果识别出其它合法的符号(比如:赋值号、大于号、小于等于号等),则把SYM则成相应的类型。如果遇到不合法的字符,把SYM置成NUL。

语法分析子程序分析:
语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的语义生成相应三元代码,并提供了出错处理的机制。语法分析主要由分程序分析过程(BLOCK)、参数变量分析过程(ParaDeclaration)、参数变量处理过程(ParaGetSub)、数组处理过程(ParaGetSub)、常量定义分析过程(ConstDeclaration)、变量定义分析过程(Vardeclaration)、语句分析过程(Statement)、表达式处理过程(Expression)、项处理过程(Term)、因子处理过程(Factor)和条件处理过程(Condition)构成。这些过程在结构上构成一个嵌套的层次结构。除此之外,还有出错报告过程(Error)、代码生成过程(Gen)、测试单词合法性及出错恢复过程(Test)、登录名字表过程(Enter)、查询名字表函数(Position)以及列出类 PCODE代码过程(Listcode)作过语法分析的辅助过程。
由PL/0的语法图可知:一个完整的PL/0程序是由分程序和句号构成的。因此,本编译程序在运行的时候,通过主程序中调用分程序处理过程block来分析分程序部分(分程序分析过程中还可能会递归调用block过程),然后,判断最后读入的符号是否为句号。如果是句号且分程序分析中未出错,则是一个合法的PL/0程序,可以运行生成的代码,否则就说明源PL/0程序是不合法的,输出出错提示即可。
下面按各语法单元分析PL/0编译程序的运行机制。

分程序处理过程:
语法分析开始后,首先调用分程序处理过程(Block)处理分程序。过程入口参数置为:0层、符号表位置0、出错恢复单词集合为句号、声明符或语句开始符。进入Block过程后,首先把局部数据段分配指针设为3,准备分配3个单元供运行期存放静态链SL、动态链DL 和返回地址RA。然后用Tx0记录下当前符号表位置并产生一条Jmp指令,准备跳转到主程序的开始位置,由于当前还没有知到主程序究竟在何处开始,所以 Jmp的目标暂时填为0,稍后再改。同时在符号表的当前位置记录下这个Jmp指令在代码段中的位置。在判断了嵌套层数没有超过规定的层数后,开始分析源程序。首先判断是否遇到了常量声明,如果遇到则开始常量定义,把常量存入符号表。接下去用同样的方法分析变量声明,变量定义过程中会用Dx变量记录下局部数据段分配的空间个数。然后如果遇到Procere保留字则进行过程声明和定义,声明的方法是把过程的名字和所在的层次记入符号表,过程定义的方法就是通过递归调用Block过程,因为每个过程都是一个分程序。由于这是分程序中的分程序,因此调用Block时需把当前的层次号Lev加一传递给Block 过程。分程序声明部分完成后,即将进入语句的处理,这时的代码分配指针CX的值正好指向语句的开始位置,这个位置正是前面的Jmp指令需要跳转到的位置。于是通过前面记录下来的地址值,把这个Jmp指令的跳转位置改成当前cx的位置。并在符号表中记录下当前的代码段分配地址和局部数据段要分配的大小(DX 的值)。生成一条INT指令,分配DX个空间,作为这个分程序段的第一条指令。下面就调用语句处理过程Statement分析语句。分析完成后,生成操作数为0的OPR指令,用于从分程序返回(对于0层的主程序来说,就是程序运行完成,退出)。
常量定义过程:
通过循环,反复获得标识符和对应的值,存入符号表。符号表中记录下标识符的名字和它对应的值。

变量定义过程:
与常量定义类似,通过循环,反复获得标识符,存入符号表。符号表中记录下标识符的名字、它所在的层及它在所在层中的偏移地址。

参变量定义过程:
类似变量定义,将参变量,存入符号表中。

参变量处理过程:
如果函数用参变量,依照形参的类型、个数,由实参进行赋值。

数组处理过程:
计算数组括号内的偏移值,存入栈顶用于后面生成的STOARR和LODARR指令调用实际的数组中元素的地址。

语句处理过程:
语句处理过程是一个嵌套子程序,通过调用表达式处理、项处理、因子处理等过程及递归调用自己来实现对语句的分析。语句处理过程可以识别的语句包括赋值语句、read语句、write语句、++语句、--语句、+=语句、-=语句、if-else-then语句、while语句、For语句、repeat 语句。当遇到begin/end语句时,就递归调用自己来分析。分析的同时生成相应的类PCODE指令。

赋值语句的处理:
首先获取赋值号左边的标识符,从符号表中找到它的信息,并确认这个标识符确为变量名。然后通过调用表达式处理过程算得赋值号右部的表达式的值并生成相应的指令保证这个值放在运行期的数据栈顶。最后通过前面查到的左部变量的位置信息,生成相应的STO指令,把栈顶值存入指定的变量的空间,实现了赋值操作。返回函数值也是用赋值语句进行返回值的储存。
对函数与过程调用的处理:
首先判断读入的标识符属性为FUNCTION或PROCEDURE,从符号表中找到此标识符,获得其所在层次和偏移地址。然后生成相应的cal指令。至于调用子过程所需的保护现场等工作是由类PCODE解释程序在解释执行cal指令时自动完成的。如果此标识符不在第0层而且是该层函数的函数名则作为返回值返回。

read语句的处理:
确定read语句语法合理的前提下(否则报错),由变量的类型生成相应的指令:
对于整型,第一条是16号操作的opr指令,实现从标准输入设备上读一个整数值,放在数据栈顶。如果读入是实数就报错,第二条是sto指令,把栈顶的值存入read语句括号中的变量所在的单元。
对于实型,第一条是15号操作的opr指令,实现从标准输入设备上读一个实数值,放在数据栈顶。第二条是sto指令,把栈顶的值存入read语句括号中的变量所在的单元。
对于字符型,第一条是20号操作的opr指令,实现从标准输入设备上读一个字符值,第二条是sto指令,把栈顶的值存入read语句括号中的变量所在的单元。

write语句的处理:
与read语句相似。在语法正确的前提下,生成指令:通过循环调用表达式处理过程分析write语句括号中的每一个表达式,生成相应指令保证把表达式的值算出并放到数据栈顶并生成指令,输出表达式的值,如果是数字类型则生成14号操作的opr指令,如果是字符类型则生成19号操作的opr指令。

if-then-else语句的处理:
按if语句的语法,首先调用逻辑表达式处理过程处理if语句的条件,把相应的真假值放到数据栈顶。接下去记录下代码段分配位置(即下面生成的jpc指令的位置),然后生成条件转移jpc指令(遇0或遇假转移),转移地址未知暂时填0。然后调用语句处理过程处理 then语句后面的语句或语句块。then后的语句处理完后,如果遇到else,就调用语句处理过程处理else语句后面的语句或语句块,这时当前代码段分配指针的位置就应该是上面的jpc指令的转移位置。通过前面记录下的jpc指令的位置,把它的跳转位置改成当前的代码段指针位置,否则没遇到else,那么此时的当前代码段分配指针的位置也是上面jpc指令的转移位置,也是通过前面记录下的jpc位置指令的位置,把它的跳转到当前的代码段指针位置。

begin/end语句的处理:
通过循环遍历begin/end语句块中的每一个语句,通过递归调用语句分析过程分析并生成相应代码。

while语句的处理:
首先用cx1变量记下当前代码段分配位置,作为循环的开始位置。然后处理while语句中的条件表达式生成相应代码把结果放在数据栈顶,再用cx2变量记下当前位置,生成条件转移指令,转移位置未知,填0。通过递归调用语句分析过程分析do语句后的语句或语句块并生成相应代码。最后生成一条无条件跳转指令 jmp,跳转到cx1所指位置,并把cx2所指的条件跳转指令的跳转位置改成当前代码段分配位置。

Repeat语句的处理:
首先用CX1变量记下当前代码段分配位置,作为循环的开始位置。然后通过递归调用语句分析过程分析,直到遇到until保留字,如果未对应until则出错。调用条件表达式处理过程生成相应代码把结果放在数据栈顶,再生成条件转移指令,转移位置为上面记录的CX1。
For语句的处理:
按For语句的语法,首先对For后面的一个标识符进行初值的赋值过程(类似赋值语句处理),生成相应的代码。之后遇到TO或DOWNTO保留字,如果未对应则出错。用CX1变量记下当前代码段分配的位置,作为以后JMP循环的开始位置。对上面识别的标识符变量进行存取,与TO或DOWNTO后面的表达式进行比较,生成比较指令(TO为13、DOWNTO为11),再用CX2变量记下当前代码段分配的位置,生成JPC指令,跳转地址未知,之后可用CX2记录下的位置进行回填。然后处理DO保留字后的循环体,第一步递归调用语句分析过程,第二步将原先For后的标识符变量进行自加处理,生成相应代码,然后生成无条件跳转语句JMP跳转代码为CX1。最后将此时的代码段位置回填到JPC跳转指令上。

表达式、项、因子处理:
根据PL/0语法可知,表达式应该是由正负号或无符号开头、由若干个项以加减号连接而成。而项是由若干个因子以乘除号,mod、div符号或++、--符号连接而成,因子则可能是一个标识符或一个数字,或是一个以括号括起来的子表达式。根据这样的结构,构造出相应的过程,递归调用就完成了表达式的处理。把项和因子独立开处理解决了加减号与乘除号的优先级问题。在这几个过程的反复调用中,始终传递fsys变量的值,保证可以在出错的情况下跳过出错的符号,使分析过程得以进行下去。

逻辑表达式的处理:
首先判断是否为一元逻辑表达式:判奇偶。如果是,则通过调用表达式处理过程分析计算表达式的值,然后生成判奇指令。如果不是,则肯定是二元逻辑运算符,通过调用表达式处理过程依次分析运算符左右两部分的值,放在栈顶的两个空间中,然后依不同的逻辑运算符,生成相应的逻辑判断指令,放入代码段。

判断单词合法性与出错恢复过程分析:
本过程有三个参数,s1、s2为两个符号集合,n为出错代码。本过程的功能是:测试当前符号(即sym变量中的值)是否在s1集合中,如果不在,就通过调用出错报告过程输出出错代码n,并放弃当前符号,通过词法分析过程获取一下单词,直到这个单词出现在s1或s2集合中为止。
这个过程在实际使用中很灵活,主要有两个用法:
在进入某个语法单位时,调用本过程,检查当前符号是否属于该语法单位的开始符号集合。若不属于,则滤去开始符号和后继符号集合外的所有符号。
在语法单位分析结束时,调用本过程,检查当前符号是否属于调用该语法单位时应有的后继符号集合。若不属于,则滤去后继符号和开始符号集合外的所有符号。
通过这样的机制,可以在源程序出现错误时,及时跳过出错的部分,保证语法分析可以继续下去。
语法分析过程中调用的其它子过程相对比较简单,请参考源程序的注释。

类PCODE代码解释执行过程分析:
这个过程模拟了一台可以运行类PCODE指令的栈式计算机。它拥有一个栈式数据段用于存放运行期数据、拥有一个代码段用于存放类PCODE程序代码。同时还拥用数据段分配指针、指令指针、指令寄存器、局部段基址指针等寄存器。
解释执行类PCODE代码时,数据段存储分配方式如下:
对于源程序的每一个过程(包括主程序),在被调用时,首先在数据段中开辟三个空间,存放静态链SL、动态链DL和返回地址RA。静态链记录了定义该过程的直接外过程(或主程序)运行时最新数据段的基地址。动态链记录调用该过程前正在运行的过程的数据段基址。返回地址记录了调用该过程时程序运行的断点位置。对于主程序来说,SL、DL和RA的值均置为0。静态链的功能是在一个子过程要引用它的直接或间接父过程(这里的父过程是按定义过程时的嵌套情况来定的,而不是按执行时的调用顺序定的)的变量时,可以通过静态链,跳过个数为层差的数据段,找到包含要引用的变量所在的数据段基址,然后通过偏移地址访问它。
在过程返回时,解释程序通过返回地址恢复指令指针的值到调用前的地址,通过当前段基址恢复数据段分配指针,通过动态链恢复局部段基址指针。实现子过程的返回。对于主程序来说,解释程序会遇到返回地址为0的情况,这时就认为程序运行结束。
解释程序过程中的base函数的功能,就是用于沿着静态链,向前查找相差指定层数的局部数据段基址。这在使用sto、lod、stoArr、lodArr等访问局部变量的指令中会经常用到。
类PCODE代码解释执行的部分通过循环和简单的case判断不同的指令,做出相应的动作。当遇到主程序中的返回指令时,指令指针会指到0位置,把这样一个条件作为终至循环的条件,保证程序运行可以正常的结束

4. 如何在Linux下配置socks5代理

您好,希望以下回答能帮助您
找到socks5-v1.0r11.tar.gz这个软件包
开始编译,安装

1
2
3
4
5

#tar xvfz socks5-v1.0r11.tar.gz
#cd socks5-v1.0r11
#./configure --with-threads
#make
#make install

开始配置
一般来说安装完后,会在/etc目录下生成socks5.conf(配置文件)和socks5.passwd(用于验证的文件)这两个文件,
下面我把我的配置文件帖出来
#/etc/socks5.conf
#指定SOCKS v5绑定的ip地址和监听的端口。如果不指定绑定的IP将使用0.0.0.0
set SOCKS5_BINDINFC 192.168.0.8:1080
#忽略ident请求。当客户机没有运行identd时,使用SOCKS5_NOIDENT将降低超时值
set SOCKS5_NOIDENT
#指定连接停顿最长时间。超过最大值后,socks5断开连接
set SOCKS5_TIMEOUT 15
#socks5将接受SOCKS V4 协议的请求,默认不接受
set SOCKS5_V4SUPPORT
#指定同时存在的最大子进程数,Socks5预设为64
set SOCKS5_MAXCHILD 4
#指定密码文件
set SOCKS5_PWDFILE /usr/local/socks5/etc/socks5.passwd

#对所有的客户连接都使用username/password用户认证方法
auth - - u

#允许来自192.168.0.的任何经过用户认证的连接
permit u - 192.168.0. - - -

#/usr/local/socks5/etc/socks5.passwd
#用户 密码
userA passwdA
userB passwdB
userC passwdC

前面的一些设置由于我在配置文件里都写了相关的内容,就不在说明了
如果不需要用户验证只需要把
auth - - u
改成 auth - - -

permit u - 192.168.0. - - -
改成
permit - - - - - -

注意上面permit - - - - - -这一句,是使任何人都可以使用你的socks5 server,非常不安全(让你作跳板),最好是有点限制

permit - - clientIP - - -

开始测试
/usr/local/socks5/bin/socks5 -f -s

如果出现下面的信息表示测试成功。

18210: Socks5 starting at Mon Dec 14 18:23:45 1998 in normal mode

然后退出socks5,开始正式运行它在背景模式:
正式运行
/usr/local/socks5/bin/socks5 -t -s 2> /var/log/socks5

最后,加到/etc/rc.d/rc.local

echo "/usr/local/socks5/bin/socks5 -t -s 2> /var/log/socks5.log"
>> /etc/rc.d/rc.local

如您还有疑问可继续追问。

5. 什么是PSOS

pSOS系统结构
pSOS是一个由标准软组件组成的,可剪裁的实时操作系统。其系统结构如图2.1所示

,它分为内核层、系统服务层、用户层。
1. 内核层
pSOS内核负责任务的管理与调度、任务间通信、内存管理、实时时钟管理、中断服

务;可以动态生成或删除任务、内存区、消息队列、信号灯等系统对象;实现了基于优

先级的、选择可抢占的任务调度算法,并提供了可选的时间片轮转调度。pSOS Kernel还

提供了任务建间通信机制及同步、互斥手段,如消息、信号灯、事件、异步信号等。
pSOS操作系统在Kernel层中将与具体硬件有关的操作放在一个模块中,对系统服务层

以上屏蔽了具体的硬件特性,从而使得pSOS很方便地从支持Intel 80x86系列转到支持MC

68XXX系列,并且在系统服务层上对不同应用系统不同用户提供标准的软组件如PNA+、
PHILE+等。
2. 系统服务层
pSOS系统服务层包括PNA+、PRPC+、PHILE+等组件。PNA+实现了完整的基于流的TCP

/IP协议集,并具有良好的实时性能,网络组件内中断屏蔽时间不大于内核模块中断屏蔽时

间。PRPC+提供了远程调用库,支持用户建立一个分布式应用系统。PHILE+提供了文件系

统管理和对块存储设备的管理。PREPC+提供了标准的C、C++库,支持用户使用C、C++语言

编写应用程序。
由于pSOS内核屏蔽了具体的硬件特性,因此,pSOS系统服务层的软组件是标准的、与

硬件无关的。这意味着pSOS各种版本,无论是对80X86系列还是MC68XXX系列,其系统服务

层各组件是标准的、同一的,这减少了软件维护工作,增强了软件可移植性。
每个软组件都包含一系列的系统调用。对用户而言,这些系统调用就象一个个可重入

的C函数,然而它们却是用户进入pSOS内核的唯一手段。
3. 用户层
用户指的是用户编写的应用程序,它们是以任务的形式出现的。任务通过发系统调

用而进入pSOS内核,并为pSOS内核所管理和调度。
pSOS为用户还提供了一个集成式的开发环境(IDE)。pSOS_IDE可驻留于UNIX或DOS

环境下,它包括C和C++优化编译器、CPU和pSOS模拟仿真和DEBUG功能。
pSOS内核机制
§3.1 几个基本概念
3.1.1 任务
在实时操作系统中,任务是参与资源竞争(如CPU、Memory、I/O devices等)
的基本单位。pSOS为每个任务构造了一个虚拟的、隔离的环境,从而在概念上,一个任务

与另一个任务之间可以相互并行、独立地执行。任务与任务之间的切换、任务之间的通

信都是通过发系统调用(在有些情况下是通过ISR)进入pSOS Kernel,由pSOS Kernel完

成的。
pSOS系统中任务包括系统任务和用户任务两类。关于用户任务的划分并没有一个固

定的法则,但很明显,划分太多将导致任务间的切换过于频繁,系统开销太大,划分太少又

会导致实时性和并行性下降,从而影响系统的效率。一般说来,功能模块A与功能模块B是

分开为两个任务还是合为一个任务可以从是否具有时间相关性、优先性、逻辑特性和功

能耦合等几个方面考虑。
3.1.2 优先级
每个任务都有一个优先级。pSOS系统支持0~255级优先级,0级最低,255级最高。0级

专为IDLE任务所有,240~255级为系统所用。在运行时,任务(包括系统任务)的优先级

可以通过t_setpri系统调用改变。
3.1.3 任务状态
pSOS下任务具有三种可能状态并处于这三个状态之一。只有通过任务本身或其他任

务、ISR对pSOS内核所作的系统调用才能改变任务状态。从宏观角度看,一个多任务应用

通过一系列到pSOS的系统调用迫使pSOS内核改变受影响任务而从运行一个任务到运行另

一任务向前发展的。
对于pSOS kernel,任务在创建前或被删除后是不存在的。被创建的任务在能够运行

前必须被启动。一旦启动后,一个任务通常处于下面三个状态之一:
①Executing (Ready)就绪
②Running运行
③Blocked阻塞
就绪任务是未被阻塞可运行的,只等待高优先级任务释放CPU的任务。由于一个任务

只能由正运行的任务通过调用来被启动,而且任何时刻只能有一个正在运行的任务,所

以新任务总是从就绪态开始。
运行态任务是正在使用CPU的就绪任务, 系统只能有一个running任务。一般runni

ng任务是所有就绪任务中优先级最高的,但也有例外。
任务是由自身特定活动而变为阻塞的,通常是系统调用引起调用任务进入等待状态

的。所以任务不可能从ready态到blocked态,因为只有运行任务才能执行系统调用。
3.1.4 任务控制块
任务控制块TCB是pSOS内核建立并维护的一个系统数据结构,它包含了pSOS Kernel调

度与管理任务所需的一切信息,如任务名、优先级、剩余时间片数、当前寄存器状态等。

在有的RTOS中,任务的状态与任务TCB所处的队列是等同的。pSOS操作系统将二者分

为两个概念,例如任务处于阻塞状态,但它的TCB却处于消息等待队列、信号灯等待队列、

内存等待队列、超时队列之一。
pSOS启动时,将根据Configuration Table中的参数kc_ntask建立一个包含kc_ntask

个TCB块的TCB池,它表示最大并行任务数。在创建一个任务时,分配一个TCB给该任务,在

撤销一个任务时,该TCB将被收回。
3.1.5 对象、对象名及ID号
pSOS Kernel是一个面向对象的操作系统内核,pSOS系统中对象包括任务、memory
regions、memory partitions、消息队列和信号灯。
对象名由用户定义(4位ASCII字符),并且在该对象创建时作为系统调用obj_CREAT
E
的一个人口参数传给pSOS Kernel。pSOS Kernel反过来赋予该对象一个唯一的32位ID号

。除obj_CREATE和obj_IDENT外,所有涉及对象的系统调用都要用到对象ID号。
创建对象的任务通过obj_CREATE就已经知道了该对象的ID号,其余任务可通过obj_
IDENT或通过全局变量(如果已经为该任务的ID号建立了一个全局变量的话)获取该对象

的ID号。对象ID号隐含了该对象控制块(如TCB、QCB)的位置信息,这一位置信息被pSO
S
Kernel用于对该对象的管理和操作,如挂起/解挂一个任务、删除一个消息队列等。
3.1.6 任务模式字Mode word.
每个任务带有一个mode word,用来改变调度决策或执行环境。主要有以下四个参


Preemption Enabled/Disabled.
Roundrobin Enabled/Disabled
Interupts Enabled/Disabled.
ASR Enabled/Disabled: 每个任务有一个通过as-catoh建立起来的异步信号服务例

程ASR。异步信号类似于软件中断。当ASR位为1时as-catch所指向的任务将会被改变执行

路径,先执行ASR,再返回原执行点。
§3.2 任务调度
3.2.1 影响动态调度效果的两个因素
pSOS采用优先级+时间片的调度方式。有两个因素将影响动态调度的效果:一是优先

级可变(通过t_setpri系统调用改变任务的优先级);二是任务模式字中的preemption

bit位和roundrobin bit位。preemption bit位决定不同优先级的任务是否可抢占,并和

roundrobin bit位一起决定任务的时间片轮转是否有效。
3.2.2 引起任务调度的原因及结果
pSOS系统中引起调度的原因有两条:
1. 在轮转方式下时间片到
2. pSOS系统调用引发任务调度。该系统调用可能是ISR发出的,也可能是某个任务发出的

pSOS任务调度的结果有两种:
1. 引起运行任务切换,这指的是
2. 不引起运行任务切换,这指的是
不论任务调度是否引发运行任务切换,都有可能引起一个或多个任务状态变迁。
3.2.3 运行任务的切换
一、何时切换
下面三种情况将引发运行任务切换:
1. 在时间片轮转方式下(此时任务模式字的roundrobin bit与preemption bit均为
enable),运行任务Task A的时间片用完,且Ready队列中有相同优先级的其它任务,则

Task A退出运行。
2. 在运行任务Task A的Mode word的preemption bit位为enable的前提下,若Task A发出

的某条相同调用引发一个优先级高于Task A的任务Task B从Block状态进入Reary状态,则

将Task B投入运行。
3. ISR使用I_RETURN系统调用,则ISR退出运行,pSOS Kernel选择Ready队列中优先级最高

的任务投入运行(这一任务并不一定是被ISR打断的前运行任务)。
二、如何切换
上述三类运行任务的切换,其具体的pSOS Kernel运作过程并非完全一样,但彼此之间

差别不大。为了简单起见,我们以
为例对切换过程作一简单叙述。这一过程可细分为4个步骤:
1. 任务A运行信息保存(_t_save proc far)
这一过程主要完成修改系统工作标志,保存切换点地址及运行信息、任务A栈调


指针保存、栈切换、参数及返址入栈等一系列工作。
2.任务A入就绪队列(void t_in_chain)
这一过程将任务A的TCB块按优先级顺序插入就绪队列。
3.选择一个高优先级任务B(void t_choice( ))
按一定算法从就绪队列中选出最高优先级任务B的TCB块,并使运行指针指向它。

4.将任务B投入运行(_t_run proc far)
从系统栈切换到任务B栈,用任务B的TCB块中保存的信息恢复上次运行被打断的

,恢
复任务运行环境,于是任务B开始继续运行。
图3.1反映了典型任务切换过程中CPU控制权的转移、各堆栈活动生命期、任务活动

生命期等信息。图中
t1,t4为切换点 t2,t3为开/关中断
Tsch=t4-t1 // Tsch为任务切换时间
Tforbid=t3-t2 // Tforbid为中断禁止时间
它们是实时操作系统最重要的两个性能指标。

热点内容
oracle存储过程游标实例 发布:2024-11-25 05:40:32 浏览:804
xpsql2000 发布:2024-11-25 05:20:20 浏览:372
如何设置安卓上拉菜单 发布:2024-11-25 05:20:12 浏览:4
为什么安卓手机做不出透明相框 发布:2024-11-25 05:13:52 浏览:491
间接结算法 发布:2024-11-25 05:12:08 浏览:759
java咖啡机 发布:2024-11-25 05:12:05 浏览:490
小白主机怎么配置 发布:2024-11-25 05:10:33 浏览:144
automator脚本 发布:2024-11-25 04:41:18 浏览:311
敲背面截图怎么弄安卓 发布:2024-11-25 04:39:18 浏览:809
安卓机关机如何设置快捷方式 发布:2024-11-25 04:16:02 浏览:636