【问题标题】:How Does Assembly Code Generation Work?汇编代码生成如何工作?
【发布时间】:2016-12-26 02:37:41
【问题描述】:

我最近一直在研究编译器设计。我已经成功地掌握了解析阶段,但是在理解代码生成的工作原理时遇到了一些麻烦。

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

  • 指令选择(贪婪平铺)
  • 指令调度
  • 注册分配

现在,指令调度有点超出了我目前正在尝试做的事情,我认为通过更多的研究和原型设计,我可能会围绕寄存器分配的图形着色算法。

让我难过的是第一步,指令选择。根据我所读到的,目标机器语言中的每条指令都由一个图块表示;目标是找到与树的最大部分匹配的指令(因此称为贪婪平铺)。

我很困惑的是,当指令与语法树实际上不是 1:1 对应时,你如何选择指令?

以基于累加器的架构(如 Z80 或 MIP 单指令架构)为例。在 Z80 上执行 16 位整数运算可能需要使用累加器或影子寄存器。

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

我的假设是否正确?

a) 一个 tile 可能由与语法树模式匹配的指令序列组成,而不仅仅是 1:1 匹配。

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

【问题讨论】:

    标签: compilation compiler-construction code-generation


    【解决方案1】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-03-04
      • 2014-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多