汇编代码生成如何工作?

时间:2016-08-19 03:03:24

标签: compilation compiler-construction code-generation

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

根据我的阅读,代码生成阶段似乎有三个主要步骤:

  • 教学选择(贪婪平铺)
  • 指令安排
  • 注册分配

现在,指令调度有点超出了我此刻想要做的事情,而且我认为通过更多的研究和原型设计,我可以将注意力集中在用于寄存器分配的图着色算法上。

困扰我的是第一步,指令选择。根据我所读到的内容,目标机器语言中的每条指令都由一个磁贴表示;并且目标是找到与树的最大部分匹配的指令(因此昵称,贪婪的平铺)。

我感到困惑的是,当他们实际上没有与语法树1:1对应时,如何选择说明?

例如,基于累加器的体系结构,如Z80或MIPs单指令体系结构。在Z80上执行偶数16位整数运算可能需要使用累加器或影子寄存器。

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

我是否正确地承担以下事项?

a)磁贴可能包含一系列与语法树模式匹配的指令,而不仅仅是1:1匹配。

b)代码生成器首先为基于堆栈的架构(或具有无限临时寄存器的架构)生成代码,并在寄存器分配阶段以某种方式扩展和替换指令。

1 个答案:

答案 0 :(得分:3)

a)磁贴可以发出任意数量的指令。例如,如果您有%x <- %y + %z之类的指令,但目标机器只有两个地址指令,那么匹配的磁贴可能会发出汇编序列(目标是第一个操作数)

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

b)允许哪种寄存器(或const或mem引用)作为指令的操作数由指令本身决定,因此指令选择阶段必须使用符号寄存器名称(伪寄存器)进行表示。寄存器分配阶段确实可以发出附加指令,例当所需类的寄存器不可用于分配时溢出/加载代码。

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