首先考虑在一个基本块的范围内生成目标代码,这样会降低难度。目标代码生成器会依次把每一条三地址中间代码变换成目标代码,并且随时考察寄存器中记录的值,以便充分利用寄存器,避免不必要的内存访问。
寄存器是有限的。在大多数的目标机中,运算时的操作数全部或者部分需要放在寄存器中。当目标代码出现了计算某变量值的运算,运算结果应该尽可能地保留在寄存器中,而不是把该变量的值存到内存单元,直到其他变量要使用该寄存器或者已到达基本块出口为止;同样,当运算结果放在寄存器中时,后续对此结果的引用应从寄存器中获得其值,而不是从内存单元中获得。
例9.1 对于如下的高级语言语句:
A:=(B+C)*D+E
如果不考虑代码效率的话,可以将其中间代码翻译成若干条汇编代码指令,如表9-3所示。
表9-3 中间代码及翻译的目标代码序列
从表9-3中可以看出,上述翻译是正确的,但其效率却不高。显然,目标代码指令(4)和(7)是多余的;并且,T1和T2是生成中间代码时引入的临时变量,在此基本块的后续代码中不会被引用,因此,指令(3)和(6)也是多余的。这样一来,在考虑了代码效率以及充分利用寄存器的前提下,可以把目标代码精简为:(www.xing528.com)
(1)MOV AX,B
(2)ADD AX,C
(3)MUL AX,D
(4)ADD AX,E
(5)MOV A,AX
要想生成简洁高效的目标代码,必须掌握一些信息才行。例如,在将T2:=T1*D翻译为目标代码时,要想省掉指令MOV AX,T1,就必须知道T1的当前值已在寄存器AX中;同样,要想省掉指令MOV T1,AX,就必须知道出了基本块之后T1不会再被引用。这些信息将通过待用信息、活跃信息、寄存器描述数组以及变量地址描述数组来记录。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。