130 likes | 210 Views
第十章 目标代码生成. 目标代码. 虚拟目标代码: 虚拟机上的目标程序。 在本地机器上具备虚拟机的解释器。 实际目标代码: 实际机器上的指令序列 绝对地址机器代码: 可重定位的机器代码: 汇编代码:. 三种硬件地址模式. 指令格式: Op R #C ( 立即-----寄存器) Op R2 d(R1) ( 存储器-----寄存器) Op R1 R2 ( 寄存器-----寄存器) 几个常见指令的含义 : LD R Source 从 Source 读出送入 R
E N D
目标代码 • 虚拟目标代码:虚拟机上的目标程序。 • 在本地机器上具备虚拟机的解释器。 • 实际目标代码:实际机器上的指令序列 • 绝对地址机器代码: • 可重定位的机器代码: • 汇编代码:
三种硬件地址模式 • 指令格式: Op R #C (立即-----寄存器) Op R2 d(R1) (存储器-----寄存器) Op R1 R2 (寄存器-----寄存器) • 几个常见指令的含义 : LD R Source 从Source 读出送入R Op R Source Source op R结果 送入R ST Target R R的内容送入Target.
表达式和赋值语句的翻译 • 形如(Op,A,B,T):LD R A;Op R B • 形如(ASSIG,A,B):LD R A;ST B R • 例:Z:= X*(a+b)* Y* (a+b)
输入/输出语句的翻译 • 输入语句:(READ, A ) IN R ST A , R • 输出语句:(WRITE,A ) LD R , A OUT R
条件语句四元式的翻译 • (THEN, t,_ , _)生成的目标代码为: LD R , t JUMP0 R , __ • (ELSE,_,_,_)生成的目标代码为: JMP __ 同时回填JUMP0指令的目的地址 • (ENDIF,_,_,_)不产生目标代码,只负责完成ELSE子句的地址回填工作 。
循环语句的翻译 • (WHILE,_,_,_)不产生目标代码,只用来标记while语句的入口地址。 • (DO , t ,_ ,_)产生的目标代码为: LD R , t JUMP0 R , _ • (ENDWHILE, _, _, _)产生的目标代码: JMP A 回填前面DO四元式所产生的半条指令
标号和goto语句的翻译 • (LABEL, _, _,L)不产生目标代码,只向L所分配到的存储单元写入转向地址。 • (GOTO, _, _, L)生成的目标代码为 JMP *L
过程、函数说明的翻译 • ( ENTRY, Q, —, —) 不产生目标代码,只需将当前指令地址A填入Q的相应语义信息中。 • (ENDPROC, —,—,—)或(ENDFUNC,—,—,—) 1. 将本层活动记录中保存的机器状态恢复过来,对应一组读指令。 2. 删除本层活动记录,使动态外层的活动记录成为当前活动记录; 3. 按1(top)中记载的返回地址返回。 目标代码为: ST top, sp LD sp , 0(top)// 作废当前活动记录 JMP 1(top)//按返回地址返回
过程、函数调用语句的翻译 • 值参情形 (ValACT , t , Offset , size ) a. 若t为间接变量,则生成的目标代码为: LD R , * t ST offset(sp) , R b. 若t 为直接变量 ,则生成的目标代码为: LD R ,t ST offset(sp) , R c. 若t 为数组,则生成的目标代码为: moveB t , offset(sp) , size
过程、函数调用语句的翻译 • 变参情形 (VarACT , t, Offset , size ) a. 若t为直接变量,,则生成的目标代码为: LEA R , t ST offset(sp) , R b. 若t为间接变量,,则生成的目标代码为: LD R , t ST offset(sp) , R
过程、函数调用语句的翻译 • 过程、函数调用语句 (CALL , f , —, t ) 1. 生成填写变量访问环境指令 2. 把机器状态(寄存器内容)保存到活动记录的机器状态区中,一般应生成一组存的指令 3. 要填写管理信息.首先填写过程层数.从过程f的语义信息中取其层数,填入到2(top)中,生成指令为 LD R , sem[f].level ST 2(top), R
4. 填写动态链指针 ST 0(top), sp 5. 填写返回地址 LD R, A+5 // A ST 1(top), R // A+1 6. 生成过程活动记录 ST sp, top // A +2 ST top, top + sem[f].size // A+3 7. 生成转向过程f入口的指令 JMP sem[f].code // A+4 8. 如果是函数调用,则把函数值读到寄存器中 LD R , 4(top)// A+5 ST t , R