汇编(assembly) 速成课

1,085 阅读3分钟

本文为翻译

原文标题:A crash course in assembly

原文作者:Lin Clark

原文地址:hacks.mozilla.org/2017/02/a-c…

这是 WebAssembly 系列文章的第三部分。如果你没读过其他的,我推荐你 从头开始

通过理解 “什么是 汇编” 和 “编译器如何产生汇编代码”,我们能更好的理解 WebAssembly 的工作原理。

讨论 JIT 的那篇文章 中,我提到过:和机器交流 就像是 和外星人交流。

image.png

我现在想谈谈 外星人的大脑是如何工作的 — 即 机器的大脑是如何解析和理解在交流中接收到的信息。

机器大脑的一部分是用来思考加法、减法 或 逻辑运算的。除此之外,还有用于提供 短期记忆 和 长期记忆 的部分。

我们为这些不同的部分进行了命名。

  • 负责思考的部分叫做 算术逻辑单元 (Arithmetic-logic Unit 简称 ALU )
  • 提供短期记忆的部分叫做 寄存器(registers)
  • 提供长期记忆的部分叫做 随机存取存储器 (Random Access Memory 简称 RAM

image.png

机器码中的语句被称作 指令 (instructions)。

当一条指令进入 机器大脑 时,会发生什么呢?它会被按照作用分割成不同的部分。

机器大脑 思考的方式,决定了 指令分割的方法。

例如,有一个 机器大脑,总是将前 6 bit 取出并传输到 ALU。ALU 根据 0 和 1 的位置关系后,辨认出这 6 bit 的含义是 “将两个东西加在一起”。

这 6 bit 就被称为 “操作码”(operation code 简称 opcode),顾名思义,ALU 根据它执行对应操作。

image.png

在这之后,这个 机器大脑 会提取后面连续的两块内容,每块 3 bit。这两块内容代表要进行相加的数字 在 寄存器 中的地址。

image.png

注意图中机器码上方的注释,这些注释帮助我们人类理解正在发生的事。这就是汇编。它被称作 符号机器码(symbolic machine code)。这是人类理解机器码的一种方式。

对于例子中的这台机器,我们能发现,它的机器码 和 汇编 之间有着相当直接的关系。其实,对于不同的机器架构,会存在不同种类的汇编。当一台机器中包含不同的架构时,它可能会需要独立的汇编方言。

也就是说,我们的 翻译 不只有一个目标。并不只有一种叫做 机器码 的语言,机器码的种类繁多。就像人类会说不同的语言一样,机器也会说不同的语言。

在 人类语言 到 外星语 的翻译过程中,可能要从英语、俄语 或 汉语 翻译到 外星语A 或 外星语B。在编程领域,这就像是从 CC++Rust 翻译到 x86ARM

为了能将 任意的高阶语言 翻译成 任意的汇编语言(对应不同的机器架构),我们可以创建 一大堆不同的 单对单 的编译器。

image.png

这肯定是相当低效的。为了解决这个问题,大多数编译器在 高阶语言 和 汇编语言 之间加入了至少一个中间层。编译器会将高阶语言的代码 翻译成介于 高阶语言 和 汇编 之间的一种语言。这被称为 中间表示(Intermediate Representation 简称 IR)。

image.png

这意味着编译器可以将任意的高阶语言 翻译成 一种 IR语言(中间语言)。而编译器的另一部分可以取到这些 IR语言,并将其编译成特定目标架构的汇编代码。

编译器的前端 将 高阶语言 翻译到 IR。编译器的后端再从 IR 翻译到 目标架构的汇编代码。

image.png

结论

我在本文中讲解了汇编的概念,还有 编译器 从 高阶语言 翻译成 汇编代码的方式。在下一篇文章中,我将介绍 WebAssembly 是如何与这些流程交互的。