第九章 目标代码生成

合集下载

目标代码生成

目标代码生成

(1 2 ) h a lt B 5
图7–1 程序流图
[解答] (1) 考虑变量a的情况:基本块B2中没有对a进行 定值,且引用的次数为1(e=a−b);基本块B3没有对a进 行定值,也没有引用a;基本块B4对a进行了定值,并 且定值前引用的次数为1(a=a−f)。根据执行代价节省数 的计算公式得到:
③ 删除RVALUE [Ri]中的M; (4) 给出R,返回。
例7.2 对例7.1,假设只有AX和BX是可用寄存器,用代码 生成算法生成目标代码和相应的RVALUE和AVALUE。
表7.2 例7.2的目标代码
四元式
目标代码
RVALUE
AVALUE
T=A−B U=A−C V=T+U
MOV AX, A SUB AX, B
和A是同一标识符,或者B在该四元式之后不再被引用,则选取Ri为所
需寄存器并转(4)。
不行则选用空闲寄存器
(2) 如有尚未分配的寄存器,则从中选取一个Ri为所需寄存器并转(4)。 再不行则选用待用位置最远的变量占用的寄存器
(3) 从已分配的寄存器中选取一个Ri为所需寄存器R。选取原则为:占用 Ri的变量的值也同时放在内存中,或者该值在基本块中要在最远的位置 才会引用到。这样,对寄存器Ri所含的变量和变量在内存中的情况必须 先做如下调整:
(1) 在原代码生成算法中,仅当变量在基本块中被定值时,其值才 存放在寄存器中。现在把寄存器固定分配给某变量使用,当该变量 在基本块中被定值前,每引用它一次就可以少访问一次内存,则执 行代价节省1。
(2) 在原代码生成算法中,如果某变量在基本块中被定值且在基本 块出口之后是活跃的,则出基本块时要把它在寄存器中的值存放到 内存单元中。现在把寄存器固定分配给某变量使用,出基本块时就 无需把它的值存放到其内存单元中,则执行代价节省2。

第9章 目标代码生成

第9章 目标代码生成

寄存器的使用准则
寄存器先行准则:尽可能把变量的值驻留到寄存器
中,尽可能用寄存器中的现行值,以减少访问内存
的次数。例:
1. (:=, 10, X) 2. (×, X, X, t1) 3. (-, X, t1, t2) 4. (:=, t2, X)
执行 1 后,把10装入到某寄存器
RX中,而不送到X的内存单元, 这样,2、3、4就可以直接从RX 中取值,而不用访问内存单元了
end GetReg
例:中间代码(三地址码): (1) t1 := z * 6 (2) x := -4 (3) if x >= 76 goto (7) (4) x := x + 4 (5) y := t1 + x (6) goto (3)
指令种类
• 赋值 MOV • 比较 CMP • ≥转移 JLE • 转移 JMP • 累加 ADD • 相乘 MUL
寄存器的分配原则是选择代价最小的寄存器,这就涉 及到代价如何计算的问题。如果申请的是空闲寄存器,则 代价自然为0,否则属于剥夺性质。当一个寄存器R被剥夺 时,R的一些占有变量的现行值可能不在内存中,而且以后 可能引用,因此要产生一些回送现行值的Store指令(ST) 和重新装入寄存器的Load指令(LD)。则R的分配代价包括:
DL:取D(Dead)或 L(Live)。如果从K+1中间
代码开始,到A重新被赋值或基本块结束都没有引
用A,则A的DL值为D;否则为L。DL值在中间代码
步骤确定。例如:
1. (+,a,b,t1) 2. (-,t1,c,t2) 3. (×,t2,b,t3) 4. (:=,t3,x)
(+,D,L,L) (-ቤተ መጻሕፍቲ ባይዱD,D,L) (×,D,D,L) (:=,D,D)

编译原理第九章 运行时存储空间组织

编译原理第九章  运行时存储空间组织
• 简单栈区(可以带递归,但不可以嵌套定义) • 复杂栈区(可以嵌套定义, pascal)
– 堆区(new, malloc)
9.5 嵌套过程语言的栈式实现
• Pascal 的过程嵌套 嵌套层次:主程序0层 ······ 采用层数计数器,每逢Proc Begin加1,遇 Proc End则减1。
• 直接外层 • 编译器需要将过程的层数记录到符号表中
2)返回函数结果:累加器、寄存器
··· a:= 3 ··· P(a); Write(a); ···
传地址 8,8 8
举例
Procedure P(x) Begin
x:=x+5; writeln(x,a); End;
传结果 8,3 8
传值 8,3 3
举例
begin
Procedure P(x,y,z) …P(a+b,a,a)
初等类型数据采用确定“字长”,数组按列存放,边界对齐。
这样,可将过程活动单元(局部数据区)直接安排在 过程目标码之后,以便运行时访问。
9.3 Fortran静态存储分配(2)
数据区
返回地址 调用程序返回地址(调用恢复地址)
寄存器保护区 保存调用程序的寄存器运行环境
形式单元 形参
简单变量 数组 临时变量
P ->S ->Q =》R ->R
Program P; var a,x…
Top
R
procedure Q(b)
SP
var i…
R
procedure R(u,v)

var c,d…

begin… R… end {R} 链
Q
begin … R… end{Q} procedure S

编译原理第三版课后习题答案

编译原理第三版课后习题答案

编译原理第三版课后习题答案编译原理是计算机科学中的一门重要课程,它研究的是如何将高级程序语言转换为机器语言的过程。

而《编译原理》第三版是目前被广泛采用的教材之一。

在学习过程中,课后习题是巩固知识、提高能力的重要环节。

本文将为读者提供《编译原理》第三版课后习题的答案,希望能够帮助读者更好地理解和掌握这门课程。

第一章:引论习题1.1:编译器和解释器有什么区别?答案:编译器将整个源程序转换为目标代码,然后一次性执行目标代码;而解释器则逐行解释源程序,并即时执行。

习题1.2:编译器的主要任务是什么?答案:编译器的主要任务是将高级程序语言转换为目标代码,包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等过程。

第二章:词法分析习题2.1:什么是词法分析?答案:词法分析是将源程序中的字符序列划分为有意义的词素(token)序列的过程。

习题2.2:请给出识别下列词素的正则表达式:(1)整数:[0-9]+(2)浮点数:[0-9]+\.[0-9]+(3)标识符:[a-zA-Z_][a-zA-Z_0-9]*第三章:语法分析习题3.1:什么是语法分析?答案:语法分析是将词法分析得到的词素序列转换为语法树的过程。

习题3.2:请给出下列文法的FIRST集和FOLLOW集:S -> aAbA -> cA | ε答案:FIRST(S) = {a}FIRST(A) = {c, ε}FOLLOW(S) = {$}FOLLOW(A) = {b}第四章:语义分析习题4.1:什么是语义分析?答案:语义分析是对源程序进行静态和动态语义检查的过程。

习题4.2:请给出下列文法的语义动作:S -> if E then S1 else S2答案:1. 计算E的值2. 如果E的值为真,则执行S1;否则执行S2。

第五章:中间代码生成习题5.1:什么是中间代码?答案:中间代码是一种介于源代码和目标代码之间的表示形式,它将源代码转换为一种更容易进行优化和转换的形式。

河北科技大学 编译原理教学大纲

河北科技大学 编译原理教学大纲

《编译原理》课程教学大纲一、教学内容和要求重点掌握:有限自动机、正规文法、正规表达式、LL(1)分析法、LR分析法、语法制导翻译等知识;掌握:递归下降分析法、优先分析法、属性文法、中间语言、运行时存储分配、代码优化、常用算法;理解:文法、语言及自动机间的关系、符号表的组织及作用、目标代码生成、查错与校错及面向对象的程序设计语言第一章绪论1.编译过程概述2.编译程序的逻辑结构3.编译程序的组织第二章前后文无关文法和语言(共7学时)1.语言、文法及其表示2.句型分析3.文法的化简与改造4.文法与语言的Chomsky分类第三章词法分析与词法分析程序1.设计词法分析程序应考虑的问题2.正规文法与状态转换图3.有限自动机4.正规表达式与正规集第四章语法分析与语法分析程序1.自顶向下的语法分析i)消除左递归ii)消除回溯的条件iii)递归下降分析iv)预测分析(LL(1)分析)2.自底向上的语法分析i)简单优先分析ii)算符优先分析iii)LR分析第五章语法制导翻译及中间代码生成1.属性文法及属性翻译文法的概念2.常见中间语言3.简单算术表达式及赋值语句的翻译4.布尔表达式的翻译5.控制语句的翻译6.含有数组元素的算术表达式及赋值语句的翻译7.过程说明及过程调用的翻译8.说明语句的翻译第六章符号表1.符号表的组织2.符号表的建立与查找第七章运行时的存储组织与分配第八章代码优化1.局部优化2.数据流分析原理3.循环优化第九章目标代码生成第十章查错与改错。

第九章 目标代码生成(1)

第九章  目标代码生成(1)

SYMBL[X( L )]
…L
a
yyy
b
yy
c
yy
d
yy
t1 n y y n
t2 n y n
t3 n y n
t4
nyn
t5
nyn
x
yn
9.1.3 寄存器的分配问题
寄存器操作快且指令短,如何充分利用它?
⒈ 设置描述表: RDL(R0,R1,…, Rn):
用以记录寄存器的当前状态:如 RDL.R1=x 如何为
此外还有下述 操作码 op :
逻辑 运算
LT(<),GT(>),EQ(==),LE(<=),GE(>=),NE(!=) AND(&&),OR(||),NO(!)
※ 四元式目标代码翻译示例:
【例9.1】
⑴( + a b t1 ) ⑵( - t1 d t2 )
①LD R0,a ②ADD R0,b ③SUB R0,d
※ 附有活跃信息的四元式:
⑴(+ a(y) b(y) t1(y ) ) ⑵(* a(y) t1(y) t3(y) ) ⑶(/ t1(y) t3(n ) x(y) ) ⑷(= t1(n) _ i(y ) )
Ⅲ. 基本块内活跃信息求解算法
• 支持: ⑴ 在符号表上增设一个信息项( L )
name … L
⑴(+ a( y ) b( y ) t1( y )) ⑵(- c( y ) d( y ) t2( y )) ⑶(* t1( y )t2( n )t3( y ))
⑷(- a( y ) t3( n )t4( y )) ⑸(/ t1( n ) 2 t5( y )) ⑹(+ t4( n )t5( n ) x( y ))

编译原理自测题附答案(有错)

编译原理自测题附答案(有错)

第一章一.填空题1.编译程序的工作过程一般可以划分为词法分析、语法分析、语义分析与中间代码产生、优化和生成目标程序等几个基本阶段,同时还伴有符号表管理和出错处理。

2.若源程序是用高级语言编写的,目标程序是汇编或机器语言,则其翻译程序称为编译程序。

3.编译方式与解释方式的根本区别在于运行目标程序时的控制权在解释器而不是目标程序。

4.翻译程序是这样一种程序,它能将用甲种语言书写的程序转换成与其等价的乙种语言书写的程序。

5.对编译程序而言,输入数据是高级语言(源)程序,输出结果是低级语言(目标)程序。

6.运行编译程序的计算机称宿主机,运行编译程序所产生目标代码的计算机称目标机。

7.当把编译程序划分成编译前端和编译后端时,前端主要由与源语言有关但与目标机无关的部分组成,编译后端包括编译程序中与目标机有关的部分,编译后端不依赖于源语言而仅仅依赖于中间语言。

8.描述词法规则的有效工具是词法分析器,通常使用语法分析器来描述语法规则,使用语义分析(与中间代码产生)器描述语义规则。

二.综合题(该答案仅供参考)1、给出C语言编译程序对下面语句进行编译时从词法分析到目标代码生成5个分析阶段的分析过程。

c=a+b*30;(1)给出每个阶段的输入和输出代码或其它数据形式。

(2)给出符号表,说明在哪些阶段会对符号表进行填写或查找。

(3)编译过程是否进行了代码优化?若有,请指出优化之处,并给出属于哪种优化?答:词法分析:出入源程序;输出识别出的记号流。

c=a+b*30 id1=id2+id3*30语法分析器:输入记号流,构造句子结构;输出语法树。

=id1 +id2 *id3 30语义分析与中间代码生成:出入语法树,输出中间代码变量地址数值注:赋值阶段会对符号表进行填写或查找1. id1 0 c (itr,30,,t1)2. id2 4 x (*,id3,t1,t2)3. id3 8 y (+,id2,t2,t3)4. t1 12 30 (=,t3,,id1)优化:1.(*,id3,30.0,t1)2.(+,id2,t1,id1)精简掉多余的复写传播mulf #30.0,r2 mov id2,r1 sub r1,r2 mov r2,id1第二章一.填空题1.上下文无关文法包括以下四个组成部分:一组终结符号,一组非终结符号,一个开始符号,以及一组产生式。

编译原理第9篇

编译原理第9篇
第36页
编译原理
第37页
编译原理
第38页
编译原理
二、嵌套层次显示表(display)和活动记录
为了提高访问非局部量的速度,还可以引用一个 指针数组,称为嵌套层次显示表。 每进入一个过程后,在建立它的活动记录区的同 时建立一张嵌套层次表display. 假定现进入的过程的层数为i,则它的display表 含有i+1个单元。 此表本身是一个小找,自顶向下每个单元依次存 放着现行层,直接外层,…,直至最外层(0层, 主程序层)等每一层过程的最新活动记录的基地 址。
第25页
编译原理 进入过程P后所做工作示意
P的数组区
第26页
返回地址
1 0
TOP
SP
P的活动记录 (长度为L)
调用过程
编译原理
(3)过程返回
C语言以及其它一些相似的语言含有return(E)的返 回语句,E为表达式。
假定E值已计算出来并已存放在某临时单元T中,可 将T只传送到某个特定寄存器(调用过程将从这个特 定的寄存器中获得P的结果)。
第14页
编译原理 简单的栈式存贮分配
适用于简单程序语言的实现:语言没有分程序结构, 过程定义不允许嵌套,但允许过程的递归调用,允许 过程含有可变数组。 C语言就是这样一种语言。其局部名称的存储分配, 可以直接采用栈式存储分配策略。
第15页
编译原理
1、栈式存储分配
使用栈式存储分配法意味着把存储组成一个栈。 运行时,每当进入一个过程(一个新的活动开 始)时,就把它的活动记录压入栈,从而形成 过程工作时的数据区,一个过程的活动记录的 体积在编译时是可静态确定的。 当该活动结束(过程退出)时,再把它的活动 记录弹出栈,这样,它在栈顶上的数据区也随 即不复存在。

编译原理自测题2014

编译原理自测题2014

注:1、章节不完全按照陈意云教材的章节;2、不公布标准答案;3、题目中标注的页码如P6图1.3均为陈意云教材的页码。

第一章一.填空题1.编译程序的工作过程一般可以划分为______、_______、_______、_______和_______等几个基本阶段,同时还伴有_______和_______。

2.若源程序是用高级语言编写的,目标程序是_______或_______,则其翻译程序称为编译程序。

3.编译方式与解释方式的根本区别在于_______。

4._______是这样一种程序,它能将用甲种语言书写的程序转换成与其等价的乙种语言书写的程序。

5.对编译程序而言,输入数据是_______,输出结果是_______。

6.运行编译程序的计算机称宿主机,运行编译程序所产生目标代码的计算机称_______。

7.当把编译程序划分成编译前端和编译后端时,_______主要由与_______有关但与目标机无关的部分组成,编译后端包括编译程序中与目标机有关的部分,编译后端不依赖于源语言而仅仅依赖于_______。

8.描述词法规则的有效工具是_______,通常使用_______来描述语法规则,使用_______描述语义规则。

二简答题1.什么是编译程序2. 什么是解释程序3. 什么是翻译程序4. 以上3种程序的区别三综合题1、编译过程的几个阶段的输入输出及相关技术(P6图1.3)第二章一综合题1.构造与正规式(a|b)*a(a|b)等价的状态最少的确定有限自动机。

2.构造与正规式(0|1)*0(0|1)等价的状态最少的确定有限自动机。

3.构造与正规式(a|ba)*等价的状态最少的确定有穷自动机。

4.构造与正规式(a|b)* aa等价的状态最少的确定有穷自动机。

注意:以上4题要分别写出构造NFA、NFA确定化为DFA(子集法)、DFA的最小化过程二简答题1、当给出有限自动机的状态转换图时,写出有限自动机的五元式定义,并判断它能识别何种字符串。

编译原理第三版答案

编译原理第三版答案

编译原理第三版答案编译原理是计算机科学中非常重要的一门课程,它涉及到程序设计语言的语法、语义和编译器的设计与实现等内容。

《编译原理》(Compilers: Principles, Techniques, and Tools)是编译原理领域的经典教材,由Alfred V. Aho、Monica S. Lam、Ravi Sethi和Jeffrey D. Ullman合著,已经出版了三个版本。

本文将针对《编译原理》第三版中的习题和答案进行整理和总结,以帮助学习者更好地理解和掌握编译原理相关知识。

第一章,引论。

1.1 什么是编译器?编译器是一种将源程序翻译成目标程序的程序,它包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等阶段。

1.2 编译器的主要任务是什么?编译器的主要任务是将高级语言程序翻译成等价的目标程序,同时保持程序的功能和性能。

1.3 编译器的结构包括哪些部分?编译器的结构包括前端和后端两部分,前端包括词法分析、语法分析和语义分析,后端包括中间代码生成、代码优化和目标代码生成。

第二章,词法分析。

2.1 什么是词法分析?词法分析是编译器中的第一个阶段,它将源程序中的字符序列转换成单词(Token)序列。

2.2 词法分析的主要任务是什么?词法分析的主要任务是识别源程序中的单词,并将其转换成单词符号表中的标识符。

2.3 词法分析中常见的错误有哪些?词法分析中常见的错误包括非法字符、非法注释、非法标识符等。

第三章,语法分析。

3.1 什么是语法分析?语法分析是编译器中的第二个阶段,它将词法分析得到的单词序列转换成抽象语法树。

3.2 语法分析的主要任务是什么?语法分析的主要任务是识别源程序中的语法结构,并检查语法的正确性。

3.3 语法分析中常见的错误有哪些?语法分析中常见的错误包括语法错误、缺失分号、缺失括号等。

第四章,语义分析。

4.1 什么是语义分析?语义分析是编译器中的第三个阶段,它对源程序的语义进行分析和处理。

程序设计语言 编译原理(第三版)第9章

程序设计语言 编译原理(第三版)第9章

TOP 32
d
31
c
30
v
29
u
28
2
27
11
SP 26 25
返回地址 17
24
d
23
c
22
v(形参)
21
u(形参)
20
2(形参个数)
19
11
18
返回地址
17
11
16
i
15
b(形参)
14 1(形参个数)
13
0
12
返回地址
11
5
10
i
9
c
8
0
7
0
6
返回地址
5
0
4
x
3
a
2
0
1
返回地址
0
0
25
9.5 嵌套过程语言的栈式实现
0
0
过程S中调 用Q时
过程P中 调用S时
23
过程Q中调用R时
TOP
24
d
23
c
22
v(形参)
21
u(形参)
20 2(形参个数)
19
11
18 返回地址
SP
17
11
16
i
15
b(形参)
14 1(形参个数)
13
0
12
返回地址
11
5
10
i
9
c
8
0
7
0
6
返回地址
5
0
4
x
3
a
2
0
1
返回地址
0
0

代码生成

代码生成
产生指令op z,L,其中z是z的当前位置之一
如果y和/或z的当前值不再引用,在块的出口也不活 跃,并且还在寄存器中,则修改寄存器描述符
9.4 一个简单的代码生成器
9.4.3 寄存器选择函数
函数getreg返回保存x := y op z的x值的位置L
如果名字y在R中,且R不含其它名字的值,并且在执
9.4 一个简单的代码生成器
9.4.1 寄存器描述和地址描述 例:对a := b + c 如果寄存器Ri含b,Rj含c,且b此后不再活跃
产生ADD Rj, Ri,结果a在Ri中
如果Ri含b,但c在内存单元,b仍然不再活跃
产生ADD c, Ri,或者 MOV c, Rj
ADD Rj, Ri
9.2 目 标 机 器
9.2.1 目标机器的指令系统
选择可作为几种微机代表的寄存器机器
四字节组成一个字,有n个通用寄存器
R0,R1, …,Rn-1。
二地址指令: op 源,目的
MOV
{将源移到目的中}
ADD
{将源加到目的中}
SUB {在目的中减去源}
9.2 目 标 机 器
地址模式和它们的汇编语言形式及相关开销
9.3 基本块和流图
9.3.4 下次引用信息
为每个三地址语句x := y op z决定x、y和z
的下次引用信息
i: x :=… := x …
. . . 没有对x的赋值
k: … := … x
9.3 基本块和流图
对每个基本块从最后一个语句反向扫描到第 一个语句,可以得到下次引用信息
B2
prod := t6
t7 := i +1
i := t7
if i <= 20 goto B2

编译原理之代码生成

编译原理之代码生成

03
04
05
1. 语法分析:根据语言 2. 语义分析:对抽象语
的语法规则,将源程序 法树进行语义检查和处
解析成抽象语法树
理,包括类型检查、符
(Abstract Syntax Tree,号表管理等。
AST)。
3. 中间代码生成:根据 抽象语法树和语义分析 结果,生成中间代码。 常见的中间代码形式有 三地址码、静态单赋值 形式(Static Single Assignment,SSA)等。
运行时系统自动管理程序中的内存资源, 通过垃圾回收机制回收不再使用的内存空 间,防止内存泄漏和野指针等问题。
运行时系统对程序性能的影响和优化
性能影响
运行时系统的设计和实现会直接影响程序的性能。例如,垃圾回收算法的选择和实现会 影响内存的回收效率和程序的暂停时间。线程调度策略的选择也会影响程序的并发性能
编译原理是计算机科学的重要分支,对于理解计算机如何执行程序以及如何提高程 序执行效率具有重要意义。
代码生成在编译过程中的作用
代码生成是编译过程的最后阶段, 负责将中间代码或优化后的代码 转换为目标机器上的可执行代码。
代码生成器需要了解目标机器的 指令集、寄存器分配、内存管理 等相关知识,以生成高效且正确
中间代码在编译器中的 作用主要有以下几点
使得编译过程分为相对 独立的前端和后端,降 低了编译器的复杂性。
提供了统一的中间表示, 便于实现不同语言之间 有利于进行各种优化操 的互操作性。 作。
ห้องสมุดไป่ตู้
中间代码生成的算法和步骤
01
02
中间代码生成的主要算 法包括语法分析、语义 分析和中间代码生成三 个步骤。
具体步骤如下
代码生成器的测试和评估方法

计算机导论教学大纲

计算机导论教学大纲

计算机导论教学大纲课程编号:09004课程名称:计算机导论英文名称:Introduction to Computer Science学分:3总学时:60(其中,授课30 学时,实验30 学时)适用年级专业:计算机科学与技术、软件工程、网络工程、应用技术、信息管理等专业)一年级一、课程说明(一)编写本大纲的指导思想《计算机导论》是学习计算机知识的入门课程,是计算机科学与技术、软件工程、网络工程等专业(统称计算机专业)的专业基础课,是计算机专业完整知识体系的绪论。

通过本课程的学习,可以使学生对计算机的发展历史、计算机专业的知识体系、计算机学科方法论及计算机专业人员应具备的业务素质和职业道德有一个基本的了解和掌握,这对于计算机专业学生四年的知识学习、能力提高、素质培养和日后的学术研究、技术开发、经营管理等工作具有十分重要的基础性和引导性作用。

(二)课程目的和要求《计算机导论》课程的课堂讲授主要应用包括:计算机发展简史、计算机专业知识体系、计算机基础知识、操作系统与网络知识、程序设计知识、软件开发知识、计算机系统安全与职业道德、计算机领域的典型问题、计算机学科方法论等内容。

常用软件的介绍和练习主要放在实验环节。

通过本课程的学习,使学生了解计算机的发展简史,激发学习兴趣;掌握计算机的基本知识,建立专业知识体系框架;熟练掌握常用的计算机软件的使用,提高操作技能;了解计算机科学技术的最新发展,促进研究性学习;掌握计算机学科的思维方法,培养综合素质与创新能力。

这对于计算机专业学生四年的知识学习、能力提高、素质培养和日后的学术研究、技术开发、经营管理等工作具有十分重要的基础性和引导性作用。

本课程定位在对计算机专业做一个绪论性的介绍,不求深度优先,但求广度优先,主要目的在于让学生对计算机的历史发展、知识体系及学习(研究)方法有一个总体性的了解,激发学生的学习兴趣和学习主动性。

(三)教学的重点、难点本课程教学的重点是计算机发展简史、计算机基础知识、操作系统与网络知识、程序设计知识、软件开发知识、计算机系统安全与职业道德、计算机学科方法论等内容。

程序设计语言与编译原理_第九章语义分析和中间代码生成

程序设计语言与编译原理_第九章语义分析和中间代码生成
• 中间语言(复杂性界于源语言和目标语言 之间)的好处:
– 便于进行与机器无关的代码优化工作 – 易于移植 – 使编译程序的结构在逻辑上更为简单明确
Compiler
Compiler
源语言 Front End 中间语 Back End 目标语
程序
言程序
言程序
10
程序设计语言与编译
• 常用的中间语言:
找包含它的最小switch、while或for语句方可找到
转向点,否则出错。
(3) 一致性检查
如在相同作用域中标识符只能说明一次、
case语句的标号不能相同、函数调用参数个数要相同
等。
程序设计语言与编译
常见的语义错误
声明和使用相关的语义错误 –标识符没有声明; –重复声明;
如何检查? –每当遇到新声明的标识符,查符号表
– 后缀式,逆波兰表示 – 图表示: DAG、抽象语法树 – 三地址代码
• 三元式 • 四元式 • 间接三元式
11
程序设计语言与编译
四元式形式: (op,ARG1,ARG2,RESULT) op—运算符 ARG1—第一运算量 ARG2—第二运算量 RESULT—结果
程序设计语言与编译 如: A:=-B*(C+D)
形如x:=y op z的赋值语句,op为二目算术
算符或逻辑算符;
赋值语句x:=op y,op为一元算符,如一元
减uminus, not, 移位及转换算符(如将定点 数转换为浮点数);
赋值语句x:=y;
无条件转移语句 goto L;
16
程序设计语言与编译
条件转移语句 if x relop y goto L 或 if a goto
» 如果当前有效的所有标识符中有相同名字的,则 是重复声明错误;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

9.3.2
代码生成算法
假设基本块中每个中间代码形式为 A=B op C。 对每条中间代码 i:A=B op C依次执行如下步骤:
(1)调用函数GETREG(i:A=B op C); (2)利用地址描述数组AVALUE[B]和AVALUE[C]确定变量B和C的现 行值存放位置B’和C’; (3)如果B’R,则生成目标代码: LD R,B’ op R,C’ ;否则 生成目标代码 op R,C’ ; 若B’或C’为R,则删除AVALUE[B]或 AVALUE[C]中的R; (4)令AVALUE[A]={R} ,并令RVALUE[R]={A}; (5)如果B和C的现行值在基本块中不再被引用,则释放所占用RK (即,删除RVALUE[RK]中的B或C以及AVALUE[B]中的RK )。
类型 直接地址型 寄存器型 变址型 间址型
2、其它指令的意义:
指令 意义 LD Ri,B (B)Ri ST Ri,B (Ri) B J X 无条件转移到X单元 CMP A,B 比较A、B单元的值,并根据A<B分别置CT为0 或1或2 J<X CT=0 则转移 J X CT=0 或 CT=1 则转移 J=X CT=1 则转移 J X CT 1 则转移 J>X CT=2 则转移 J X CT=2或 CT=1则转移
接上页:

按上述算法给出的结点次序, T[1],T[2],…,T[N],可以把DAG重新 生成一个等价的中间代码序列,根据 新序列中的中间代码次序,运用前面 的代码生成算法生成的目标代码较优。
9.4



代码生成器的自动生成技术
机器体系结构不统一 自动生成的代码的质量、生成速度 与机器无关的优化
各中间代码对应的目标代码:
序号 中间代码 1 A=B op C 2 A= op B 目标代码 序号 中间代码 LD Ri,B 6 goto X op Ri,C 7 if A rop B LD Ri,B goto X op Ri,Ri LD Ri,B 8 A=P LD Rj,I 9 P =A LD Ri,B(Rj) LD Ri,B LD Rj,I ST Ri,A(Rj) 目标代码 J X’ LD Ri,A CMP Ri,B J rop X’ LD Ri,*P LD Rj,A ST Ri,*P
第 9章

目标代码生成
以源程序的中间代码作为输入,产生等价 的目标代码作为输出,如图。
编译前端 中间 代码 代码优化 中间 代码生成器 代码 目标程序
源程序
符号表
代码生成器的输入包括中间代码和符号表中
的信息; 代码生成是把语义分析后或优化后的中间代 码变换成目标代码。
9.1
概述
1. 代码生成器的输入: 源程序的中间表示:如三地址代码; 符号表中的信息:在数据区中的相对地址 2. 目标程序: 绝对机器语言代码; 可再定位机器语言代码; 汇编语言程序。
计算变量待用信息的算法:
(1)开始时,符号表中各变量为“非待用”,变量在出口 之后是否活跃填入活跃信息栏; (2)从基本块出口到入口由后向前依次处理各个中间代 码。对每一条代码 i: A:=B op C,执行步骤:
把符号表中变量A的待用和活跃信息附加到中间代码i上; 把符号表中A的待用和活跃信息置为“非待用”、“非活 跃”; 把符号表中变量B.C的待用和活跃信息附加到中间代码i上; 把符号表中B.C的待用信息置为i,活跃信息置为“活跃”。
例 考察基本块 (1)T=A-B (2)U=A-C
(3)V=T+U
(4)W=V+U
寄存器描述和变量地址描述
1、在代码生成过程中,建立寄存器描述数组 RVALUE,动态地记录各reg是空闲的、已分 配给某个变量、或已分配给某几个变量。 2、在代码生成过程中,建立变量地址描述数 组AVALUE,动态地记录各变量现行值的存 放位置:是在某个reg中、在某主存单元中、 或在某reg和主存单元中。
优 化
为了能够进行上述优化,代码生成器必须了解 一些信息:
9.3.1

待用信息与活跃信息
变量在基本块内的待用信息:从基本块的 出口由后向前扫描,对每个变量建立相应 的待用信息链和活跃变量信息链。 简化:基本块中的所有临时变量均看作基本 块出口之后的非活跃变量;所有非临时变 量均看作基本块出口之后的活跃变量。
把目标机的每条指令的形式描述作为输入 将中间语言代码与这种描述进行匹配来产生相 应的指令。
问题:

采用由形式描述驱动的技术:

小结:


在基本块内,利用DAG重排中间代码生成目 标代码的次序,以得到较少的目标代码; 充分利用寄存器,使目标代码的执行更快; 选择合适的指令,使生成的指令序列更短 更高效。
接上页: 置初值; FOR K=1 TO N DO T[K]=null; i=N; WHILE 存在未列入T的内部结点 DO BEGIN 选一个未列入T但其全部父结点均已入T或无父结点的内部 结点n; T[i]=n; i=i-1; WHILE n的最左子结点m不为叶结且其全部父结均已入T中 DO BEGIN T[i]=m; i=i-1; n=m END END;
acde f:=a-d cdef
B2
acdf B3 e:=a-c
B4
bdef
分配好寄存器后,就可以生成目标代码。
与简单代码生成器不同之处在于: (1)固定分配了寄存器的变量用相应reg表示; (2)循环前置结点中存值到寄存器; (3)循环出口结点中存值到主存单元; (4)循环中每个基本块的出口,未固定分配 reg的变量按需要回存到主存单元,固定分 配了reg的变量不须回存到主存单元。
9.1
概述
代码生成着重考虑两个问题:( 优化 )

如何使生成的目标代码较短; 如何充分利用寄存器,减少目标代码访 问存储单元的次数。
9.2


假想的目标机器模型
采用一个模型作为目标机器:
1、具有多个寄存器,regs可作为累加器或变址 器;具有四种类型的指令形式
指令形式 op Ri,M 运算符op包括:ADD、SUB、 op Ri, Rj MUL、DIV等 op Ri,c(Rj) op Ri,*M op Ri, *Rj op Ri,*c(Rj)
9.3 简单代码生成器
功能:依次把每条中间代码变换成目标代码, 并且在一个基本块的范围内考虑充分利用 寄存器。
例:A=(B+C)*D+E
中间代码: T1=B+C T2= T1 *D A= T2 +E
(1) LD (2) ADD (3) ST (4) LD (5) MUL (6) ST (7)LD (8)ADD (9)ST
对基本块中的中间代码序列,按怎样的次 序来生成目标代码? 改写为如下中间代码 序列G’: T2=C+D T3=E-T2 T1=A+B T4=T1-T3
例 考查如下中间代码 序列G: T1=A+B T2=C+D T3=E-T2 T4=T1-T3
DAG的目标代码
G的目标代码:
1 2 3 4 5 6 7 8 9 10 LD ADD LD ADD ST LD SUB LD SUB ST R0,A R0,B R1,C R1,D R0,T1 R0,E R0,R1 R1,T1 R1,R0 R1,T4
G’的目标代码:
1 2 3 4 5 6 7 8 LD ADD LD SUB LD ADD SUB ST R0,C R0,D R1,E R1,R0 R0,A R0,B R0,R1 R0,T4
省去了 ST R0,T1 LD R1,T1
结论:Leabharlann 对表达式X=A*B+C*D的求值,从右往左算得到的 目标代码较优。 利用基本块的DAG,将基本块的中间代码序列 重新排列。 给DAG中的N个内部结点重新排序的算法:
LD
R0,d
B0
LD
a:=b+c acde f:=a-d cdef
B2
R1,b
bcdf B1 d:=d-b e:=a+f acdef b:=d+f
acdf B3 e:=a-c bdef ST R0,d R1,b
B6
cdef b:=d+c bcdef ST
ST
B4
R0,d
R1,b
B5
ST
5

DAG的目标代码
R,B R,C R, T1 R, T1 R,D R, T2 R, T2 R,E R,A
例:
(1) LD (2) ADD (3) ST (4) LD (5) MUL (6) ST (7)LD (8)ADD (9)ST R,B R,C R, T1 R, T1 R,D R, T2 R, T2 R,E R,A (1) LD (2) ADD (5) MUL (8)ADD (9)ST R,B R,C R,D R,E R,A

把变量a的值调入寄存器时,应替换哪个寄存 器的内容才能计算更快?
对于循环,把可用的几个寄存器固定分配给节省 执行代价最多的那几个变量。 节省代价计算公式: [USE(M,B)+ 2*LIVE(M,B)]
BL
其中,USE(M,B)=基本块B中对M定值前引用M的次数; LIVE(M,B)=1(当M在B中被定值且在B的出口之后是活跃的) 0(其他情况)
B) 2 * LIVE(M, B)] [USE(M,
BL
USE(M, B) 基本块B中对M定值前 引用M的次数 1 LIVE(M, B) 0 如果M在基本块B中 被定值且在B的出口之后 是活跃的 其它情况
a:=b+c
bcdf B1 d:=d-b e:=a+f acdef b:=d+f cdef b:=d+c bcdef
相关文档
最新文档