11目标代码生成概要.pptVIP

  • 16
  • 0
  • 约9.92千字
  • 约 52页
  • 2018-03-07 发布于湖北
  • 举报
11目标代码生成概要

例11.1: 赋值语句d:=(a-b)+(a-c)+(a-c)的四元式序列: T1:=a-b T2:=a-c T3:=T1+T2 d:=T3+T2 其中d是基本块出口之后的活跃变量。 利用上述算法计算出有关变量的待用信息。 附加在中间代码上的引用信息及活跃信息 序号 四元式 左值 左操作数 右操作数 1 2 3 4 T1:=a-b T2:=a-c T3:=T1+T2 d:=T3+T2 (3,Y) (3,Y) (4,Y) (N,Y) (2,Y) (N,N) (N,N) (N,N) (N,N) (N,N) (4,Y) (N,N) 表中的(×,×)表示变量的待用信息和活跃信息。其中 数值 i 表示待用信息(即下一个引用点的中间代码编号),Y表示活跃,N表示非待用或非活跃; 符号表中的引用信息及活跃信息 变量名 引用信息及活跃信息 T1 a b c T2 T3 d (N,N)?(3,Y)?(N,N) (N,N) ?(2,Y) ?(1,Y) (N,N) ?(1,Y) (N,N) ?(2,Y) (N,N) ?(4,Y) ?(3,Y) ?(N,N) (N,N) ?(4,Y) ?(N,N) (N,Y) ?(N,N) 符号表中(×,×)?(×,×)表示在算法执行过程中后面的符号对将替代前面的符号对。 11.3.3 寄存器描述和地址描述 对寄存器的利用有两种形式:寄存器的分配和指派。 寄存器的分配: 决定让哪个变量使用某个寄存器。在使用期间,这个寄存器就存放该变量的值。 寄存器指派: 为一个变量选择一个专用寄存器,称为把寄存器指派给该变量。 如8086中,CX寄存器专用于循环计数器。如果程序中某个变量是一个循环变量,就应该把CX指派给它。 在为中间代码i: A:=B op C中变量A分配寄存器时,应遵循以下原则: (1) 如果B已在某个寄存器Ri中,且以后不再引用,则选择Ri;若B虽不再被引用,但活跃,而且Ri的值不在内存中,就生成一条存数指令MOV B , Ri; (2) 从空闲寄存器中选择一个寄存器Ri; (3) 从已分配寄存器中选取其值在最远的将来才会使用的寄存器Ri。如果Ri中的内容不在内存中,则要生成一条存数指令MOV M , Ri,把Ri中的内容存入M单元中。 为管理寄存器的使用情况。代码生成算法定义了寄存器描述数组rvalue和地址描述数组avalue,记录寄存器的内容和各变量的地址。 1.寄存器描述数组记录每个寄存器的当前内容。当需要新的寄存器时,首先查看此数组。 假定在初始时寄存器数组指示所有的寄存器均为空。当对基本块进行代码生成时,每个寄存器在任一时刻将保留零个或多个变量的值。 2.地址描述数组记录运行时的某变量的当前值存放的位置:寄存器中?存储单元?或二者中?这一信息可以存放在符号表中,用来确定对一个名字的存取方式。 寄存器号 变量VAR 内存MEM AX ??? BX …… VAR栏表示寄存器Ri分配给了哪些的变量;MEM栏表示占用Ri的那几个变量同时又在内存中。 11.3.4 基本块的代码生成算法 在分析基本块内各变量的待用信息和活跃信息,并且确定寄存器的分配策略之后,就可以给出基本块的代码生成算法。 它把构成一个基本块的中间代码序列作为输入。假设基本块中每个语句形如x:=y op z。 如果基本块中含有其它形式的语句,仿照下述算法。 算法中使用了以下过程: 1.getreg ( i: x:=y op z) : 一个函数过程,返回一个用来存放x的当前值的寄存器R。 2.addr(y) : 获得变量y的当前存放位置,只要y在寄存器中就返回R,否则y在内存中; 3.fill(y , R) : 如果变量y不在rvalue(R)中,则填入;如果y同时又在内存中,则把y填入avalue(R)中; rvalue(R)表示寄存器R分配给哪些变量, avalue(R)表示占用R的变量哪几个同时又在内存中; 4.genobj (OP R , x):向目标文件中输出指令OP R , x ; 5.delete ( y , R ):如果y在rvalue(R)和avalue(R)中,删除其中的y。 基本块的代码生成算法 输入: i: x:=y op z 输出:目标代码,并将其存入目标文件OBJ中 getreg ( i:x := y op z) //将返回的R分配给x 2. if addr(y) ≠ R then { genobj(MOV R , addr(y) ) genobj(OP R , addr(z)) } else { genobj(OP R , addr(z)) delete(y

文档评论(0)

1亿VIP精品文档

相关文档