第十章 目标代码生成
?目标代码 (单寄存器 )
?临时变量的存储空间分配
?寄存器的分配和释放
目标代码
?虚拟目标代码,虚拟机上的目标程序。
在本地机器上具备虚拟机的解释器。
?实际目标代码,实际机器上的指令序列
绝对地址机器代码:
可重定位的机器代码:
汇编代码:
三种硬件地址模式
? 指令格式:
Op #C R ( 立即 -----寄存器 )
Op d(R1) R2 ( 存储器 -----寄存器 )
Op R1 R2 ( 寄存器 -----寄存器)
? 几个常见指令的含义,
Load Source R 从 Source 读出送入 R
Op Source R Source op R结果 送入 R
Store Target R R的内容送入 Target.
目标代码的生成(单寄存器)
? 形如( Op,A,B,T),Load A R; Op B R
? 形如 (ASSIG,A,B),Load A R; Store R B
? 例,Z:= X*(a+b)* Y* (a+b)
(+,a,b,t1) Load a R; Add b R
(*,X,t1,t2) Store R t1; Mult X R
(*,t2,Y,t3) Mult Y R
(*,t3,t1,t4) Mult t1 R
标号和 Jump的代码
? 标号到代码地址的对应表( flag,L,Addr)
? 形如 (Label L),
当对应表中没有 L项时,填写表项 (1,L,Pc),Pc表示
下一条目标代码的地址。
当有 L项 (0,L,P’)时,从 P’顺着链回填地址 Pc
? 形如 (Jump L):
对应表中没有 L项时构造链头 P:(Jump,nil):
填写表项 (0,L,P);
当有表项 (0,L,P’)时,拉链 P:(Jump P’),修改表项为
(0,L,P);
当有表项 (1,L,P)时,取出 L的地址 P生成代码。
过程 /函数调用的代码
?主要工作:
过函调用时,申请新 AR空间 参数传递 转向
过程体
过函入口,填写 AR的相关内容。
过函返回时,释放 AR区 恢复信息 返回值
?参数传递的代码:
值参:
(VALACT,a,off,1),Load a(sp) R
Store off(top) R
(VALACT,A,off,1),Load @A(sp) R
Store off(top) R
变参:
(VARACT,a,off,1),LoadA a(sp) R
Store off(top) R
(VARACT,A,off,1),Load A(sp) R
Store off(top) R
过函形参:
(PROCACT,p,off,1),Load Enter(p) R
Store off(top) R
(PROCACT,P,off,1),Load P(sp) R
Store off(top) R
? 过函调用 Call,传参;
(Call,g,True),Jump Enter(g)
(Call,G,False),Jump @G(sp)
? 入口 (Entry,Label,size,Level),
填写 AR信息;
Load top sp ADD top size
? 出口 (ENDPROC,---):
恢复调用前的信息和寄存器内容;
保存返回值; Load sp top;
Load DyL(sp) sp; Jump Re_A(top)
临时变量
?特点,寿命短; 一次定义一次使用
?存储空间,尽可能采用共享办法
随用随分配的动态分配:
调用一个过程时,分配一个新的 AR空间 (不包括临
时变量部分 ),每当要保存一个临时变量时,动态
分配到栈区的可用单元中
按共享法静态分配:
先计算出临时变量的空间,在过程调用时和源变量
一起申请空间。即调用时将临时变量安排在 AR中。
临时变量的静态分配
? 定值点,如果 i中间代码给临时变量 T定值,
则称 i为临时变量 T的定值点。
? 引用点,如果 j中间代码使用 T,则称 j为 T的
引用点。
? 活动区间,如果 i是 T的定值点,j是 T的最后
引用点,则称 [i,j]是 T的活动区间。
? 活动区间 [i,j]和 [m,n]不严格相交:
如果 m?j或 i ?n。
? 空间分配:
如果两个临时变量的活动区间不严格相交,则可以
共享单元
T1
T2
T3
T4
T5
Offset = m
Offset = m+1
Offset = m+1
Offset = m+1
Offset = m
例:
寄存器
?寄存器的分类:
可分配寄存器
保留寄存器
零用寄存器
?寄存器的使用准则:
寄存器先行准则
寄存器活跃准则
寄存器多载准则
?变量的状态描述:
寄存器的分配
?分配原则,选择代价最小的寄存器
?寄存器状态描述:
?寄存器的选择代价:
Store代价
Load代价