1、1,编译原理,主讲:汤浪平,2,课程信息,教学目的与要求:编译程序是现代计算机系统的基本组成部分之一。本课程重点讲述编译程序的设计原理和常用实现技术。通过课程的学习和实验的完成,应该清楚的理解一个编译程序是如何工作的;如果在以后遇到了任何一个程序设计语言,应该知道如何实现这个语言的编译机制;应具有一定的使用编译构造工具开发编译程序的经验;会将所学的常用技术和算法应用于类似的软件的设计和实现中。,3,教材及主要参考书,教材:编译原理及实现孙悦红编,清华出版社 参考书:程序设计语言 编译原理(第3版),陈火旺、刘春林等,国防工业出版社 2000 编译原理 吕映芝编,清华出版社,4,教学内容,1 编
2、译程序概述 编译程序是现代计算机系统的基本组成部分之一。它一般由词法分析程序,语法分析程序,中间代码生成程序,目标代码生成程序,代码优化程序,符号表管理程序和错误处理程序等成分构成。,5,教学内容,2 高级语言的认识 要学习和构造编译程序,理解和定义程序设计语言是必不可少的。每个程序设计语言都有一定的规则用以规定合适程序的语法结构,也需要有对一个程序的含义的描述。上下文无关文法给出程序设计语言的精确的、易于理解的语法说明。尚没有公认的形式系统描述程序含义,但也有流行的描述语义规则的方法属性文法。 3 词法分析程序的自动构造词法分析程序是编译程序的一个构成部分,它的主要任务是扫描源程序,按构词规
3、则识别单词,并报告发现的词法错误。正则表达式和有穷状态自动机分别作为单词的描述工具和识别机制,成为词法分析程序的自动构造原理。,6,教学内容,4 语法分析程序的构造 自顶向下的语法分析。可以看作是为一个输入串寻找一个最左推导的过程,也等价于从根开始,按前序生成结点,为输入串构造分析树的过程。讨论一种有效的无回溯的自顶向下分析程序,这种分析程序称为预测分析程序。 自底向上(自下而上)语法分析方法,也称移进-归约分析法。它的实现思想是对输入符号串自左向右进行扫描,并将输入符逐个移入一个后进先出栈中,边移进边分析,一旦栈顶符号串形成可归约串,就用相应非终结符代替可归约串,这称为一步归约,重复这一过程
4、,直到归约到栈中只剩文法的开始符号时,则为分析成功,并确认输入串是文法的句子。,7,教学内容,5 语义分析和中间代码生成在词法分析和语法分析之后,编译程序下一个逻辑阶段的任务是语义分析和生成中间代码。引入属性文法和语法制导的翻译的概念,介绍中间代码的形式,针对一些语法成分讨论相应语义处理工作的描述。 6 符号表介绍符号表的一般组织和使用方法,讨论分程序结构语言的名字作用域分析及符号表设计方案。,8,教学内容,7 运行时的存储组织和管理编译的最终目标是生成目标程序。在目标代码生成前,编译程序必须对目标程序运行时的数据空间进行组织和安排。介绍目标程序运行时的数据空间的存储分配策略,说明程序设计语言
5、本身关于名称的作用域和生存期的规则与存储分配策略的关系,重点讨论栈式动态存储方案。,9,教学内容,8 代码优化和目标代码生成代码优化是对代码作一些等价变换,以使得最后生成的目标代码更为高效。介绍优化技术,优化分类以及优化工作的基础控制流和数据流分析问题。编译的最后一个逻辑阶段是目标代码生成。目标代码生成程序的设计细节要考虑目标语言和操作系统的特点。讨论目标代码生成程序设计的一般问题,包括指令选择,寄存器分配和计算顺序选择。,10,教师联系信息,汤浪平 Email: langping_ Tel: 15920136696 QQ: 43051344,11,第1章 编译系统概述,1.1 程序设计语言的
6、发展 1.2 基本术语解释 1.3 编译程序的组成 1.4 编译程序的结构 1.5 编译程序的前端和后端 1.6 TEST语言与编译器,12,编译程序概述,1程序设计语言之所以能由专用的机器语言发展到现今通用的多种高级语言,就是因为有了编译技术。编译技术是计算机专业人员必须具备的专业基础知识,它涉及程序设计语言、形式语言与自动机、计算机体系结构、数据结构、算法分析与设计、操作系统以及软件工程等各个方面。程序员大多数使用各种高级语言编写程序,而计算机只能识别用二进制数表示的指令和数所构成的机器语言程序,用高级语言编写的程序不能直接在机器上运行,要想运行它并得到预期的结果,必须将源程序转换成等价的
7、目标程序,这个转换过程就是所谓的编译。,13,1.1 程序设计语言的发展,汇编语言(Assemble Language),机器语言(Machine Language),程序设计语言(Programming Language),14,计算表达式3*16+2的值,实现该计算的机器语言程序、汇编语言程序和程序设计语言(C语言)程序如下所示。,2203 8210 2602 6101 1000 f000,Load R0,3 Mul R0,10 Load R1,2 Add R0,R1 Write R0 Halt,void main(void) cout3*16+2; ,注:10表示16,15,机器语言机器
8、指令集合称为机器语言。机器指令即二进制数,通常由若干字节构成。 优点 计算机可直接识别执行 可充分利用硬件特性,缺点 可读性差 指令系统随机种而异 由于机器指令直接或间接含有绝对地址,增加或减少一条指令,可能会引起多条指令的修改。 编程者需协调内存的使用所以,机器语言形式的程序编制和维护困难,限制了计算机的推广和应用。,16,汇编语言用记忆符取代二进制位,存储地址和汇编语句的序号可用符号名表示。 优点 用符号取代二进制数,提高了程序的可理解性。 性能较好的汇编语言,可用符号名来表示存储地址和汇编语句序号,这样避免了在汇编语句中绝对地址的出现。 可充分利用硬件特性所以,汇编语言在一定程度上降低了
9、程序编制和维护的难度。,缺点 汇编语句和机器指令基本上是一对一的,所以汇编语言的编程效率并没有质的提高。 和机器语言一样,汇编语言依附于目标计算机。 需汇编程序,将汇编语言译成机器语言。,17,程序设计语言程序设计语言又称高级语言。程序设计语言接近于英语,相当于工程语言。目前计算机系统一般含有多个程序设计语言的翻译程序(例VC、VB等),甚至对同一个程序设计语言配备了多个不同性能的翻译程序,供用户选择使用。 优点 独立于具体计算机,面向过程(函数)或对象。 程序设计语言接近于英语,可理解性好。 数据类型丰富,各种功能的语句齐备,一条语句至少相当于几十条汇编语句。所以,程序设计语言极大地提高了编
10、程效率,大幅度地降低了编程难度。 缺点 需翻译程序,将高级语言译成机器语言或汇编语言。 对硬件操作困难,高级语言通常提供汇编语言接口。,18,1.2 基本术语解释,源语言和源程序(Source Language and Source Program) 用程序设计语言书写的程序,称为源程序,该程序设计语言称为源语言。源程序通常用编缉程序输入,用字符(ASCII码)表示,以文本文件形式存储。 文本文件(Text File) 文本文件的内容由94个图形字符!-(33-126)和4个控制字符换行(10)、回车(13)、空格(32)、TAB(9)构成,文本文件又称为ASCII码文件,扩展名通常为TXT,
11、文件尾用控制字符EOF(26)指示。当换行和回车二个控制字符从文本文件读入内存,在C语言中是用一个字符(换行)表示。,19,目标语言和目标程序(Target Language and Target Program)目标语言可以是机器语言(二进制数),也可以是汇编语言(字符),或者是其它中间语言(字符),但最终结果必定是机器语言。机器语言程序用二进制文件存储,汇编语言或中间语言程序用文本文件存储。目标程序是经翻译程序加工后用目标语言表示的程序。 二进制文件(Binary File)二进制文件由机器指令即二进制数构成,因二进制数可能是26,故文件尾用文件长度(文件的字节数)指示,扩展名通常为EXE
12、。,20,翻译程序(Translator)将源程序译成逻辑上等价的目标程序的程序。翻译程序有二种工作方式:编译和解释。,解释程序 Interpreter,源程序,结果,输入数据,解释、执行,解释方式主要特点是:用户程序是消极的。用户程序运行时,控制点在解释程序,即用户程序的执行离不开解释程序。,解释方式(Interpret)以源程序作为输入,输入一句解释执行一句,不产生完整的目标程序,相应的翻译程序称为解释程序(Interpreter) 。,工作方式如下图所示:,21,编译方式(Compile)将源程序全部译为目标程序,该目标程序可在操作系统环境下直接执行,相应的翻译程序称为编译程序(Comp
13、iler) ,工作方式如下图所示:,编译程序 Compile,连接程序 Link,装入运行 Run,编辑程序 Edit,ASCII码,二进制(整体未定位),二进制(整体定位),源程序,结果,输入数据,22,编辑程序的工作结果是ASCII码形式的源程序。 编译程序以ASCII码形式的源程序为输入,它的工作结果是二进制形式的目标程序,但并未包括用户程序中所使用的系统函数的目标代码。从整体上来看,程序是不完整的,程序中的部分地址尚未确定(例系统函数的调用)。 将二进制形式的用户程序和系统函数目标代码连接成一个程序,对未确定的地址进行定位。 由操作系统将用户程序装入内存后运行。程序在运行过程中读入数据
14、,经处理加工后输出计算结果。,编译方式主要特点是:用户程序是积极的。用户程序执行时,控制点在用户程序自身。除操作系统外,程序运行无需其它支撑软件。,23,二种翻译方式比较解释方式和编译方式的主要区别是:目标代码的执行方式不同,基本原理和方法没有本质上的区别。 1)解释方式的优点 提供一种直接的交互调试功能,容易获得较好的动态调试效果。 使用变量可不预先定义。 变量性质可动态修改。 2)解释方式的缺点 在执行时需动态地对程序进行分析翻译,开销大,其执行速度相当于编译方式的1/10至1/100。 解释方式占用内存大显然解释程序的优点就是编译程序的缺点,反之亦然,对于编译程序的优缺点不再重复叙述。
15、对任何一种高级语言,既可采用编译方式,也可采用解释方式,包括汇编语言在内(MASM方式和DEBUG方式)。,24,分类,软件:计算机系统中的程序及其文档。 系统软件:居于计算机系统中最靠近硬件的一层,其他软件一般都通过系统软件发挥作用。他和具体的应用领域无关,如编译系统和操作系统等。 语言处理系统:把软件语言书写的各种程序处理成可在计算机上执行的程序。 软件语言:用于书写软件的语言。它主要包括需求定义语言,功能性语言,设计性语言,程序设计语言以及文档语言。,25,术语,编译程序(compiler) 编译程序的源语言(源程序) (source language)(source program)
16、编译程序的目标语言(目标程序) (object or target language)(object or target program) 编译程序的实现语言(implementation language) 语言处理程序(language processor) 语言转(变)换(language transformation),1.3 编译程序的组成,按照编译程序的执行过程和所完成的任务,编译分成前后两个阶段:分析阶段和综合阶段。 分析阶段根据源语言的定义,分析源程序的结构,检查源程序是否符合语言的规定,确定源程序所表示的对象和规定的操作,并以某种中间代码形式表示出来。 综合阶段根据分析结果构
17、造所要求的目标代码程序。 符号表用来记录分析过程中识别出的标识符及有关信息。如果在编译过程中发现源程序有错误,不仅要报告错误、还要进行错误处理,使编译能继续进行。,27,1.3.1词法分析程序,词法分析又称扫描器。词法分析依次读入源程序中的每个字符,依据语言的构词规则,识别出一个个具有独立意义的最小语法单位,即“单词”,并用某个单词符号来表示每个单词的词性是标识符、还是分界符、还是数等等。表示单词词性的单词符号可采用整数码或有意义的记号来表示。例如,表达式a=10+c*20经词法分析其结果如图1.4所示。 词法分析就好比在自然语句中挑出句子中的各种词汇并给出词性。如猴子吃香蕉,分析结果为:猴子
18、(名词)、吃(动词)、香蕉(名词)。 而在编译程序的词法分析中,同样是识别各种单词,只是单词的词性用某中记号或整数类码来表示。,图1.4词法分析结果,28,1.3.2.语法分析程序,语法分析:将词法分析的结果,根据语言规则,将一个个单词符号组成语言的各种语法类。如发现有不合语法规则的,要把这些出错点及错误性质报告程序员。 语法分析与语文中分析句子成分类似,根据句子由主语、谓语组成,谓语由动词、宾语组成等语言规则,分析过程常用语法树来表示句子。如“猴子吃香蕉”的语法分析树如图1.5。,29,1.3.2.语法分析程序,语法分析中,按同样的方式依据程序设计语言的语法规则进行语法归类。如表达式a=10
19、+c*20,经词法分析可得出a为标识符、10为整数等等,其语法树如图1.6所示。如果在分析过程中,无法将某个单词符号进行语法归类,则表示该表达式有语法错误。,30,1.3.3语义分析及中间代码生成程序,语义分析:确定源程序的语义是否正确。 “小明打篮球”语义正确 “篮球打小明”语义错误 在程序设计中,语义错误有很多,编译程序不能都识别出来。 语义分析主要能识别的语义错误有变量没声明就使用、变量重复声明、运算对象类型是否匹配等等。 例如分析表达式A+B时,当分析到+操作时,语义分析程序就要分析A、B是否已经声明、是否具有兼容的类型、是否已经有值。为了识别出这些语义错误,语义分析要使用编译程序中建
20、立的许多表。语义分析程序通常将源程序生成一种中间表示形式,即中间代码。中间代码具有易于产生、易于翻译成目标程序的特点,可看成是一种抽象机的指令代码,31,例如表达式(a+b)*(c+d) 翻译成四元的中间代码如下: (+ , a , b , t1) (+ , c , d , t2) (* , t1 , t2 , t3),1.3.3语义分析及中间代码生成程序,LOAD a 将a的内容加载到操作数栈 LOAD b 将a的内容加载到操作数栈 ADD 将操作数栈顶的两个单元的内容相加 STO t1 将操作数栈顶的内容存入单元t1 LOAD c 将c的内容加载到操作数栈 LOAD d 将d的内容加载到操
21、作数栈 ADD 将操作数栈顶的两个单元的内容相加 STO t2 将操作数栈顶的内容存入单元t2 LOAD t1 将t1的内容加载到操作数栈 LOAD t2 将t2的内容加载到操作数栈 MULT 将操作数栈顶的两个单元的内容相乘 STO t3 将累加器的内容存入单元t3,翻译成某个抽象机的汇编指令代码:,32,1.3.4.代码优化,代码进行优化的目的:提高目标程序的执行效率。代码优化首先在中间代码上进行。在局部范围可能做的优化有常数表达式的计算或根据操作符的某些性质如可结合性、可交换性和分配性以及检测公共子表达式进行优化,有四元式指令代码如下: (*,3.14,2,t1) (=,t1,_,x)
22、(*,2,5,t2) (*,t2,a,t3) (=,t3,_,y) (+,x,1,t4) (=,t4,_,z),而优化后的代码如下: (=,6.28,_,x) (*,10,a,y) (=,7.28,_,z),代码优化不是编译程序的必要组成部分,不同的编译程序所进行的代码优化程度差别很大,能够完成代码优化的编译程序称为“优化编译程序”。,33,1.3.5.目标代码生成,编译的最后一步是将中间代码生成特定机器上的低级语言代码。这部分与机器类型有关,对程序中的每个变量指定存贮单元,把中间代码的指令翻译成等价的某种类型机器的机器指令代码或汇编指令代码。 目标代码的形式可以是绝对指令代码、可重定位的机器
23、指令代码或汇编指令代码。如果目标是绝对指令代码,则可立即执行。如果是汇编指令代码,还需经汇编程序翻译后才能运行。现在多数编译程序产生的是可重定位的机器指令代码,这种目标代码在运行前必须借助于一个连接装配程序把各个目标模块(包括系统提供的库模块)连接在一起,确定程序中的变量在内存中的位置,装入内存中指定起始地址,使之成为一个可以运行的绝对指令代码程序。,34,1.3.6.符号表管理,编译过程中要记录源程序中出现的标识符,并收集每个标识符的各种属性信息。在词法分析中,对所有的标识符都用一个统一的符号表示,这个符号代表的标识符是变量名、函数名还是其它对象名?如果是变量名,变量的类型是什么?如果是函数
24、名,编译程序怎么知道参数的个数、类型及函数返回值的类型等信息呢? 符号表是由若干记录组成的数据结构,每个标识符在表中有一条记录,每条记录有多个域,每个域记载标识符的一个属性。例如下面一条记录说明标识符aaa是整型变量及分配的内存地址。,标识符的各种属性是在编译的不同阶段填入符号表的。词法分析阶段只能分析出标识符名,语法分析阶段只能判断标识符在语句中出现是否合法,只有到了语义分析阶段,才能将标识符的各种属性填入符号表并使用这些属性生成中间代码。,35,1.3.7.错误处理,编译的各个阶段都可能发现源程序中的错误。发现错误后如果立即停止编译,往往会降低调试程序的效率,所以应对出现的错误做适当的处理
25、,从而使编译能继续进行。词法分析可以检测出源程序中的非法符号。语法分析能够发现程序语句中的各种语法错误,如括号不匹配等等。语义分析能判断运算对象的类型是否匹配、变量是否重复声明或没声明就使用等错误。任意时刻发现错误,都应该报告错误信息,包括错误出现的位置、错误性质等,为程序员调试程序提供方便。,36,1.4 编译程序的结构,在设计和实现编译程序时,要考虑编译程序分“遍”的问题。所谓一“遍”是指编译程序在编译时把源程序或中间形式从头到尾扫描一遍,并做相关的处理,生成新的中间形式或目标代码。在一遍扫描中,可完成编译程序五个任务中的一个或几个。采用不同的分遍方式,编译程序的结构也有所不同。,37,1
26、.4.1单遍编译程序,单遍编译程序只对源程序进行一遍扫描,就完成编译的各项任务,产生目标代码。在单遍编译程序中,不产生中间代码,往往以语法分析程序为中心,词法分析和语义分析作为语法分析的子程序。其工作过程如下: 当语法分析需要读进一个新单词时,就调用词法分析子程序。词法分析子程序则从源程序中依次读入字符,组合成单词符号,并将单词符号返回给语法分析程序。 当语法分析程序识别出一个语法成分时,就调用语义分析子程序进行语义分析,并生成目标程序。 当源程序处理完后,进行善后处理,优化目标程序。 典型的单遍编译程序结构如图1.7所示。,词法分析,源程序,取单词,目标程序,开始,语法分析,语义分析及代码生
27、成,送单词,图1.7单遍编译程序结构,38,1.4.2多遍编译程序,有的编译程序把编译程序的五项任务分几遍来进行,每遍只完成部分任务, 典型的多遍编译程序结构如图1.8所示。 多遍编译程序的工作过程如下: 调用词法分析程序将高级语言源程序转换成用单词符号表示的程序,即将字符串程序转换成单词符号串源程序。 调用语法分析程序对符号串源程序进行语法归类检查。 调语义分析程序进行语义检查,并生成中间的代码程序。 调用代码优化程序对中间代码程序进行优化。 调用目标生成程序将优化后的中间代码程序转换成目标代码程序。,图1.8,39,1.4.3编译程序分遍的优缺点,编译程序是否分遍、如何分遍,要根据计算机内
28、存大小、源程序语言的复杂性和目标程序的质量要求而定。 编译程序分为多遍,其优点是: 可以减少内存容量的需求。分遍后,以遍为单位分别调用编译的各个程序,各遍程序可以相互覆盖; 可使各遍的编译程序相互独立,结构清晰; 能够进行充分的优化,产生高质量的目标程序; 可将编译程序分为“前端”和“后端”(见下节),有利于编译程序的移植。 但分遍也有缺点,主要是每遍都要读符号、送符号,增加了许多重复性工作,降低编译效率。目前的编译程序中,有单遍的,也有二遍的、三遍的,还有多到十几遍的。,40,1.4.4“端”的概念,根据编译程序的各部分涉及的内容,可将编译的组成部分划分成“前端”和“后端”。前端主要与源语言
29、有关,包括词法分析、语法分析、语义分析和中间代码生成、符号表的建立以及相应的错误处理和符号表操作。后端主要与目标机器有关,包括代码优化、目标代码生成以及相应的错误处理和符号表操作。 把编译程序分为前端和后端的优点是便于移植、编译程序的构造。比如有M种高级语言、N种目标机器,如果不分前端和后端,就需要建立M*N套编译程序,而分成前端和后端,可先建立M套前端编译程序将M种高级语言翻译成相同的中间语言,再建立N套后端翻译程序将中间语言翻译成N种机器的目标语言,这样只需要建立M套前端编译程序和N套编译程序后端编译程序,不仅程序个数减少,而且每端只包含编译程序的部分任务,更加易于实现。,41,1.5 编
30、译程序的前后处理器(di 1 ci),源程序往往分许多模块并保存在不同的文件中,编译前应将这些不同文件中保存的程序连接起来。有些语言为了提高编程效率还提供了一些“预处理命令”,例如C语言的宏定义#Define、文件包含#include等等。这样在进行编译前就需要有一个预处理器将各种源文件连接起来,将宏扩展成源语言语句。图1-9显示一个语言从框架源程序到可运行程序,处理系统的各个部分。,图1-9,42,1.5.1预处理器,编译之前,预处理器对源程序进行处理,产生标准源程序。不同语言的预处理功能有所不同,C语言编译系统的预处理器主要完成以下几个功能: 宏处理:C语言允许用户在程序中定义宏,以便提高
31、编程效率,如#defing PI 3.1415926是一个宏定义,那么在编译之前,预处理器要将源程序中的所有符号PI换成3.1415926。 文件包含:如果C源程序中含有#include “stdio.h”,那么预处理器处理到这条语句时,就用stdio.h的实际内容替换该语句。 条件编译:并非源程序的每一行都要进行编译,有时情况不同要编译不同的语句。C语言预处理器处理条件编译,将真正要编译的语句组成标准源程序。,43,1.5.2 汇编程序,有些编译程序只产生汇编语言目标代码,这样就需要汇编程序做进一步翻译,生成可重定位的机器代码。可重定位的机器代码可以装载到内存的任何地方,这种代码采用相对地址
32、,起始地址为0,各条指令及所访问的地址都是相对应于0的逻辑地址。如果加载到内存单元L处,则所有指令地址及访问的地址都要加上L。 汇编语言采用助记符表示操作码,用标识符表示存储地址,如完成a=b+2的80x86汇编语言程序如下:MOV b,R1ADD #2,R1MOV R1,a 其中a,b表示存储地址,R1表示寄存器,#2表示立即常数。有些汇编语言还提供宏指令来提高汇编语言编程效率,这种汇编语言称为宏汇编语言。,44,1.5.3 连接装入程序,连接装入程序完成两个主要任务: 连接:把几个可重定位的机器代码文件连接成一个可执行的程序,这些文件可能是分别编译得到的,也可能是由系统提供的库文件。 装入
33、:读入可重定位的机器代码,根据装入地址修改将重定位地址转换成物理地址,并存储到内存中。,45,1.6.1 TEST语言,TEST语言的程序结构很简单,它在语法上相当于C的函数体:是由一对花括号扩起来的语句序列。另外,它既无过程也无函数。表达式语句以及控制语句的写法都与C语言类似,一条声明语句只能声明一个整型简单变量、没有数组,控制语句只有三个: if、while和for语句,这三个控制语句本身也可包含语句序列,表达式也局限于布尔表达式和整型算术表达式。布尔表达式由对两个算术表达式的比较组成,该比较使用、=、=和!=比较算符。算术表达式可以包括整型常数、变量、参数以及4个算符+、*、/,此外还有
34、一般的数学属性。另外,还可以有复合语句。为了能实现输入输出,添加了read语句和write语句。在花括号中可以有注释,注释用“/*”和“*/”括起来,但注释不能嵌套。,例如,下段程序就是采用TEST语言编制的计算阶乘的程序。 int i;int n;int j;j=1;read n;for (i=1;i=n;i=i+1)j=j*i;write j; ,46,1.6.2 TEST编译器,TEST编译器包括以下的C文件, TESTmain.c: 主程序,先后调用词法分析、语法分析及语义分析和代码生成。 TESTscan.c: 词法分析,接收用TEST语言编写的程序,输出的单词符号程序将作为语法分析
35、的输入。 TESTparse.c:语法、语义分析及TEST机的汇编代码生成,如果有错误,报告错误。,47,1.6.3 TEST机,用一个抽象机的汇编语言作为TEST编译器的目标语言。TEST机的指令仅能作为TEST语言的目标。实际上,TEST机具有精减指令集计算机的一些特性。TEST机的模拟程序直接从一个文件中读取汇编代码并执行它,因此避免了由汇编语言翻译为机器代码的过程。但是,这个模拟程序并非是一个真正的汇编程序,它没有符号地址或标号。因此, TEST机编译器必须仍然计算跳转的绝对地址。此外为了避免与外部的输入/输出例程连接的复杂性,TEST机有内部整型的I / O设备;在模拟时,它们都对标准设备读写。附录C列出了用C语言编写的TEST机模拟程序。,48,习题 一,1.1 高级程序设计语言有那些特点? 1.2 典型的编译程序可划分为几部分?各部分的主要功能是什么?每部分都是必不可少的吗? 1.3 解释方式和编译方式的区别是什么? 1.4 论述多遍扫描编译程序的优缺点。 1.5 解释下列名词:源程序、目标程序、翻译程序、汇编程序、编译程序、遍,