Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

生成汇编代码

复习

  • 指令选择:决定用哪些机器指令
  • 寄存器着色与溢出:决定值放在哪里
  • 栈帧:函数调用时的栈布局

TL;DR

  • 生成汇编,是把前面所有决定落成具体的文本
  • 此时指令、寄存器、栈位置都已确定
  • 汇编之后还要经汇编器变成机器码
  • 后端到此基本完成

正文

  这是后端代码生成的最后一步。前面的决定——用哪些指令、每个值放哪个寄存器、栈帧怎么摆——都做好了,现在要做的,是把它们写成具体的汇编代码

把决定“抄”下来

  到了这一步,其实“思考”已经基本结束,剩下的更像“誊写”:

  • 指令选择已经定了 ××× 用哪条指令
  • 寄存器分配已经定了每个变量待在哪个寄存器
  • 栈帧布局已经定了局部变量和溢出值在栈上的偏移

  生成汇编,就是把这些决定,按机器的语法一字一句写出来。

一个例子

  比如这样一段简单代码 a = b + c,经过前面的处理,可能被生成成:

load  r1, [b]     ; 把 b 从内存读进寄存器 r1
load  r2, [c]     ; 把 c 读进 r2
add   r3, r1, r2  ; r3 = r1 + r2
store [a], r3     ; 把结果写回 a

  原本一句 a = b + c,被拆成了“取数、取数、相加、存回”几条指令。这和我们前面讲三地址码时的“拆解”,思路一脉相承——只不过这次拆的是真正的机器指令

  如果 bc 已经在寄存器里,或者机器支持“基址 + 偏移”的寻址模式,生成的指令还会更少。具体长什么样,取决于前面指令选择和寄存器的决定。

之后还有什么

  汇编代码并不是终点。它还要交给汇编器,翻译成二进制的机器码,生成目标文件;再经过链接,才能变成可执行文件。

  这两步——汇编和链接——我们在讲程序与编程基础时提过,当时当作黑箱。现在我们已经走到了它们的门口。下一组,就正式打开链接这个黑箱。

思考题 1

  到“生成汇编”这一步,哪些决定已经确定了?

思考题 2

  生成的汇编,之后还要经过什么,才能变成可执行文件?

小结

知识点

  • 生成汇编把指令、寄存器、栈布局落成文本
  • 简单语句会被展开成多条机器指令
  • 汇编再经汇编器变为机器码,生成目标文件
  • 之后还需链接才能得到可执行文件

参考资料

  1. Wikipedia(zh):汇编语言:与机器指令对应的低级语言
  2. Wikipedia(zh):代码生成:后端生成目标代码的过程

思考题答案(仅供参考)

思考题 1

  指令选择(用哪些机器指令)、寄存器分配(每个值放在哪个寄存器或内存)、以及栈帧布局(局部变量与溢出值在栈上的位置)都已经确定,生成汇编只是把这些决定写成具体的汇编文本。

思考题 2

  汇编代码要先经汇编器翻译成二进制机器码,形成目标文件;多个目标文件还要再经过链接,解决符号与地址的引用,才能最终得到可执行文件。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪