汇编快速入门

2,818 阅读4分钟

本文是 WebAssembly 系列文章的第三部分。如果你还没有阅读过前面的文章,我们建议你 从头开始

理解汇编和编译器如何生成它的有助于你后续理解 WebAssembly 的工作原理,

介绍 JIT 的文章里,我谈到了与机器交流的方式和与外星人通信是相似的。

一个人用源代码示意,外星人以二进制回应

我现在真想看看外星人大脑的思考方式——即机器大脑解析和理解通信的机制。

大脑中有一部分专门用来思考(例如做加减或其他逻辑运算),一部分提供短期记忆存储,还有一部分提供长期记忆存储。

这几个不同的部分都有各自的名称:

  • 负责思维的部分称为算术逻辑单元 (ALU)。
  • 短期存储由寄存器提供。
  • 长期存储由随机存取存储器 (RAM) 提供。

图为 CPU,包含 ALU、寄存器和 RAM

机器码中的句子被称为指令。

当一条指令进入大脑时会发生什么?它会被分解成带不同含义的不同部分。

指令分解的方式是特定于当前大脑构造的。

例如,这种结构的大脑可能总是将前六个字节传送给 ALU。ALU 根据接收到的序列中 1 和 0 的排列,就会明白需要将两个东西加在一起。

这个字段称为操作码(opcode),它的作用是告诉 ALU 要执行的操作。

从 16 字节指令中取出 6 个字节并传送给 ALU

接下来大脑会取后续两个三字节的字段来确定要相加的两个数。这两个数会存储在寄存器中。

两个 3 字节字段被解码用以确定源寄存器

注意这里机器码上方的注释,有助于我们理解这个过程。这就叫做汇编。这段代码称为符号机器码。符号机器码是人类理解机器码的一种方式。

你会发现汇编和这台机器的机器码有很直接的关系。因此不同的机器架构对应有不同的汇编方式。当你遇到使用不同架构的机器时,可能就得按它们自己的方式进行汇编。

因此,我们的翻译对象并不止一个。机器码不止一种语言,有许多不同种类的机器码。就像我们人类会说不同的语言一样,机器也会使用不同的语言。

随着人类和外星人之间的翻译问题解决,你也可以将英语、俄语、普通话等语言转化成外星文A、外星文B了。对编程而言,就是将 C、C++、Rust 等语言转化成 x86、ARM。

如果你想将任意一种高级语言编译成对应任意体系结构的汇编语言,一种方法是创建一整套不同语言到不同汇编的转化器。

图中左侧为编程语言 C、C++ 和 Rust,右侧为汇编语言 x86 和 ARM,各组合分别以箭头连接

但这样的做法非常低效。大部分编译器会在中间放置至少一个中间层。编译器接收高级编程语言并将其转化成相对底层的形式,转化结果也不能和机器码一样直接运行。这类形式称为(IR)。

图中解释了高级语言和汇编语言以及中间表示(IR)的关系,箭头由高级编程语言指向 IR,又由 IR 指向汇编语言

这意味着编译器可以将任意一种高级编程语言翻译成一种 IR 语言。编译器的另一部分将得到的 IR 内容编译成特定于目标架构的语言。

编译器的前端部分将高级编程语言翻译成 IR 语言,再由后端将它们从 IR 语言编译成目标架构的汇编代码。

与上图相同,增加了前端和后端的注释

总结

以上就是汇编的简要说明,以及编译器将高级程序语言转成汇编的过程。在下一篇文章里,我们将会看到 WebAssembly 是如何实现的。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOSReact前端后端产品设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划