前几节课,我带你尝试不通过 IR,直接生成汇编代码,这是为了帮你快速破冰,建立直觉。在这个过程中,你也遇到了一些挑战,比如:
你要对生成的代码进行优化,才有可能更好地使用寄存器和内存,同时也能减少代码量;
另外,针对不同的 CPU 和操作系统,你需要调整生成汇编代码的逻辑。
这些实际体验,都进一步验证了20 讲中,IR 的作用:我们能基于 IR 对接不同语言的前端,也能对接不同的硬件架构,还能做很多的优化。 既然 IR 有这些作用,那你可能会问,IR 都是什么样子的呢?有什么特点?如何生成 IR 呢?
本节课,我就带你了解 IR 的特点,认识常见的三地址代码,学会如何把高级语言的代码翻译成 IR。然后,我还会特别介绍 LLVM 的 IR,以便后面使用 LLVM 这个工具。
首先,来看看 IR 的特征。
介于中间的语言
IR 的意思是中间表达方式,它在高级语言和汇编语言的中间,这意味着,它的特征也是处于二者之间的。
与高级语言相比,IR 丢弃了大部分高级语言的语法特征和语义特征,比如循环语句、if 语句、作用域、面向对象等等,它更像高层次的汇编语言;而相比真正的汇编语言,它又不会有那么多琐碎的、与具体硬件相关的细节。
相信你在学习汇编语言的时候,会发现汇编语言的细节特别多。比如,你要知道很多指令的名字和用法,还要记住很多不同的寄存器。在 22 讲,我提到,如果你想完整地掌握 x86-64 架构,还需要接触很多指令集,以及调用约定的细节、内存使用的细节等等(参见 Intel 的手册)。