2016-08-19 61 views
1

最近我一直在研究编译器的设计。我已经成功掌握了解析阶段,但在理解代码生成的工作方式方面遇到了一些麻烦。汇编代码生成如何工作?

从我读过的东西,似乎是在代码生成阶段3个主要步骤:

  • 指令选择(贪婪平铺)
  • 指令调度
  • 寄存器分配

现在,指令调度稍微超出了我目前所要做的,并且我认为通过更多的学习和原型设计,我可以将我的思想包围在图形公司用于寄存器分配的loring算法。

什么残缺我是第一步,指令选择。从我读到的内容来看,目标机器语言中的每条指令都由一个图块表示;目标是找到匹配树最大部分的指令(因此称为昵称,贪婪的平铺)。

我很困惑的事情是,当它们没有实际上与语法树1:1对应时,如何选择指令?例如,基于累加器的体系结构(如Z80或MIP单指令体系结构)。在Z80上执行甚至16位整数运算可能需要使用累加器或影子寄存器。

还有一些说明只能用于某些寄存器,尽管它们是通用的。

我是否正确地承担以下事项? a)瓦片可以由匹配语法树模式的指令序列组成,而不仅仅是1:1匹配。 b)代码生成器首先为基于堆栈的体系结构(或具有无限临时寄存器的体系结构)生成代码,并在寄存器分配阶段以必要的方式扩展和替换指令。

回答

2

a)瓦片可以发出任意数量的指令。举例来说,如果你有一个像%x <- %y + %z指令,但目标机只有两个地址指令,然后匹配牌可能会发出装配顺序(目标是第一个操作数)

mov %x, %y 
add %x, %z 

二)什么样的寄存器(或const,或mem引用)允许作为指令的操作数由指令本身决定,因此指令选择阶段必须用符号寄存器名称(伪寄存器)来表示。寄存器分配阶段的确可以发出添加指令,例如当需要的类的寄存器不可用于分配时溢出/加载代码。

检查 Survey on Instruction Selection: an Extensive and Modern Literature Review