汇编、编译与解释

汇编程序基本原理

汇编语言是为特定的计算机设计的面向机器的符号化的程序设计语言。因为计算机不能直接识别和运行符号语言程序,所以要用专门的翻译程序——汇编程序进行翻译。

汇编程序的功能是将用汇编语言编写的源程序翻译成机器指令程序。汇编程序的基本工作包括将每一条可执行汇编语句转换成对应的机器指令;处理源程序中出现的伪指令。

由于汇编指令中形成操作数地址的部分可能出现在后面才定义的符号,所以汇编程序一般需要两次扫描源程序才能完成翻译过程。

(1)第一次扫描

第一次扫描的主要工作是定义符号的值并创建一个符号表ST,ST记录了汇编时所遇到的符号的值。

另外,有一个固定的机器指令表MOT1,其中记录了每条机器指令的记忆码和指令的长度。

在汇编程序翻译源程序的过程中,为了计算各汇编语句标号的地址,需要设立一个位置计数器或单元地址计数器LC,其初值一般为0。在扫描源程序时,每处理完一条机器指令语句或与存储分配有关的伪指令,LC的值就增加相应的长度。

此外,在第一次扫描中,还需要对于定义符号值有关的伪指令进行处理。为了叙述方便,可以设立为指令表POT1。POT1表的每一个元素只有两个域:伪指令助记符和相应的子程序入口。

(2)第二次扫描

第二次扫描的任务是产生目标程序。

除了使用前一次扫描生成的符号表ST外,还要使用机器指令表MOT2,该表中的元素有机器指令助记符、机器指令的二进制操作码、格式和长度等。

此外,还需要设立一个伪指令表POT2,供第二次扫描时使用。POT2的每一元素仍有两个域:伪指令记忆码和相应的子程序入口。与第一次扫描的不同之处是:在第二次扫描中,伪指令有着完全不同的处理。

在第二次扫描中,可执行汇编语句应被翻译成对应的二进制代码机器指令。这一过程涉及到两方面的工作:一是把机器指令助记符转换成二进制机器指令操作码,这可以通过查找MOT2表来实现;而是求出操作数区各操作数的值(用二进制表示)。在此基础上,就可以装配出用二进制代码表示的机器指令。

编译程序基本原理

编译程序的功能是把某高级语言书写的源程序翻译成与之等价的目标程序(汇编语言或机器语言)。

汇编、编译与解释_第1张图片

编译程序的工作过程可以分为6个阶段,在实际的编译器中可能会将其中的某些阶段结合在一起进行处理。
汇编、编译与解释_第2张图片

(1)词法分析

源程序可以简单地被看成是一个多行的字符串。

词法分析阶段是编译过程的第一个阶段,这个阶段的任务是对源程序从前到后(从左到右)逐个字符的扫描,从中识别出一个个的“单词”符号。“单词”符号是程序设计语言的基本语法单位,如关键词、标识符、常数、运算符等。

词法分析程序输出的“单词”常以二元组的方式输出,即单词的种别和单词自身的值。

词法分析过程依据的是语言的词法规则,即描述“单词”结构的规则。例如PASCAL语言的一条声明语句和赋值语句:

VAR X,Y,Z:real;
X:=Y+Z*60;

词法分析阶段将构成这条语句的字符串分割成如下的单词系列。

(1)保留字 VAR
(2)标识符 X
(3)逗号 ,
(4)标识符 Y
(5)逗号
(6)标识符 Z
(7)冒号 :
(8)标准标识符 real
(9)分号 ;
(10)标识符 X
(11)赋值号 :=
(12)标识符 Y
(13)加号 +
(14)标识符 Z
(15)乘号 *
(16)整常数 60
(17)分号 ;

对于标识符X,Y,Z,其单词种别都是id(用户标识符),字符串“X”“Y”“Z”都是单词的值;而对于单词60,整常数是该单词的种别,60是该单词的值。下面用id1、id2和id3分别代表X、Y、Z,强调标识符的内部标识由于组成该标识符的字符串不同而有所区别。

经过词法分析后,声明语句“VAR X,Y,Z:real;”表示为“VAR id1,id2,id3:real;”,赋值语句“X:=Y+Z60;”表示为“id1:=id2+id360;”。

(2)语法分析

语法分析的任务是在词法分析的基础上,根据语言的语法规则将单词符号序列分解成各类语法单位,如“表达式”“语句”“程序”等。

语法规则就是各类语法单位的组成规则,通过语法分析确定整个字符串是否构成一个语法上正确的程序。

如果源程序中没有语法错误,语法分析后就能正确地构造出其语法树;否则指出语法错误,并给出相应的诊断信息。如下图为语法分析后输出的语法树:
汇编、编译与解释_第3张图片

词法分析和语法分析在本质上都是对源程序的结构进行分析。

(3)语义分析

语义分析阶段分析各语法结构的含义,检查源程序是否包含静态语义错误,并收集类型信息供后面的代码生成阶段使用。只有语法和语义都正确的源程序才能翻译成正确的目标代码。

语义分析的一个主要的工作就是进行类型分析和检查。程序设计语言中的一个数据类型一般包含两个方面的内容:类型的载体及其上的运算。例如,整除取余运算符只能对整型数据进行计算,若其运算对象中有浮点数就认为是类型不匹配的错误。

在确认源程序的语法和语义之后,即可对其进行翻译并给出源程序的内部表示。对于声明语句,需要记录所遇到的符号信息,所以应进行符号表的填查工作。
汇编、编译与解释_第4张图片
在上面的符号表中,每一行存放一个符号的信息,分别存放了每个符号的值、类型和地址。

语义分析后也会输出语法树,其中增加了一个语义处理结点inttoreal,该运算用于将一个整型数转换为浮点数。

(4)中间代码生成

中间代码生成阶段的工作是根据语义分析阶段的输出(符号表和语法树)生成中间代码。

“中间代码”时一种简单且含义明确的记号系统,可以有若干种形式,它们的共同特征是与具体的机器无关。

最常用的一种中间代码是与汇编语言指令非常相似的三地址码,其实现方式常采用四元式。四元式的形式为:(运算符,运算对象1,运算对象2,运算结果)

对于赋值语句X:=Y+Z60,可写成以下四元式序列:
(inttoreal,60,-,t1)
(
, id3,t1,t2)
(+, id2,t2,t3)
(:=, t3,-,id1)

其中,t1、t2、t3是编译程序生成的临时变量,用于存放临时的运算结果。

(5)代码优化
由于编译器将源程序翻译成中间代码的工作是机械的、按固定模式进行的,因此,生成的中间代码往往在时间和空间上有较大的浪费。为了能够生成高效地目标代码,就必须要进行代码优化,优化过程可以在中间代码生成阶段进行,也可以在目标代码生成阶段进行。

由于中间代码不依赖于具体的机器,此时所做的优化一般建立在对程序的控制流和数据流分析的基础之上,与具体的机器无关。

优化所依据的原则是程序的等价变换规则。在生成X:=Y+Z60的四元式后,60是编译时已知的常数,把它转换成60.0的工作可以在编译时完成,没有必要生成一个四元式,同时t3仅仅用来将其值传递给id1,也可以将其简化掉,因此上述的中间代可优化成下面的等价代码:
(
,id3,60.0,t1)
(+,id2,t1,id1)

(6)目标代码生成

目标代码生成是编译器工作的最后一个阶段。这一阶段的任务是把中间代码变换成具体机器上的绝对指令代码、可重定位的指令代码或汇编指令代码,这个阶段的工作与具体的机器密切相关。

使用两个寄存器R1和R2,可对上述的四元式生成下面的目标代码:
MOVF id3 R2
MULF #60.0, R2
MOVF id2, R1
ADDF R2, R1
MOVF R1, id1

这里用#表示60.0为常数。

解释程序基本原理

解释程序是另一种语言处理程序,在词法、语法和语义分析方面与编译程序的工作原理基本相同,但是在运行用户程序的时候,它直接执行源程序或源程序的中间表示形式。

汇编、编译与解释_第5张图片

解释程序不会产生源程序的目标程序,这是它和编译程序的主要区别。下图显示了解释程序实现高级语言的三种方式。
汇编、编译与解释_第6张图片
上图中A是源程序被直接解释执行的处理方式;B和C都是先将源程序翻译成中间代码,再对中间代码进行解释执行,它们的区别在于中间代码的级别,在C方式下,解释程序采用的中间代码更接近于机器语言。

编译与解释的比较

(1) 效率。编译比解释方式可能取得更高的效率。
(2) 灵活性。由于解释程序需要反复的检查源程序,这也使得解释方式能够比编译方式更灵活。
(3) 可移植性。解释方式一般比编译方式的可移植性好。

你可能感兴趣的:(计算机系统基础)