汇编语言速成

这是关于 WebAssembly 及其速度优势的系列文章的第三部分。如果您还没有阅读其他部分,我们建议您 从头开始阅读

为了理解 WebAssembly 的工作原理,了解什么是汇编语言以及编译器如何生成汇编语言是有帮助的。

在关于 JIT 的文章 中,我谈到了如何与机器进行通信就像与外星人进行通信一样。

A person holding a sign with source code on it, and an alien responding in binary

现在我想看看外星大脑是如何工作的——机器的大脑是如何解析和理解传入的通信的。

这个大脑的一部分专门用于思考——例如加减或逻辑运算。大脑附近还有一部分提供短期记忆,以及另一部分提供长期记忆。

这些不同的部分有不同的名称。

  • 进行思考的部分称为算术逻辑单元 (ALU)。
  • 短期记忆由寄存器提供。
  • 长期记忆是随机存取存储器 (或 RAM)。

A diagram showing the CPU, including ALU and Registers, and RAM

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

当其中一条指令进入大脑时会发生什么?它会被分成不同的部分,这些部分具有不同的含义。

指令的划分方式取决于这个大脑的内部连接。

例如,一个内部连接是这样的大脑可能会始终取前六位并将其传输到 ALU。ALU 会根据 1 和 0 的位置确定它需要将两个东西加在一起。

这个部分称为“操作码”或操作代码,因为它告诉 ALU 执行什么操作。

6-bits being taken from a 16-bit instruction and being piped into the ALU

然后,这个大脑会取接下来的两个三位的部分,以确定它应该将哪两个数字加在一起。这些将是寄存器的地址。

Two 3-bit chunks being decoded to determine source registers

请注意机器代码上方的注释,这使我们人类更容易理解正在发生的事情。这就是汇编语言。它被称为符号机器代码。它是人类理解机器代码的一种方式。

您可以在此处看到这种机器的汇编语言和机器代码之间存在非常直接的关系。因此,您拥有的每种类型的机器架构都有不同类型的汇编语言。当机器内部有不同的架构时,它很可能需要自己的汇编语言方言。

因此,我们的翻译目标不仅仅是一个。它不仅仅是一种名为机器代码的语言。它是许多不同种类的机器代码。正如我们人类说不同的语言一样,机器也说不同的语言。

在人与外星人翻译中,您可能从英语、俄语或普通话翻译成外星语 A 或外星语 B。在编程术语中,这就像从 C、C++ 或 Rust 翻译成 x86 或 ARM。

您希望能够将所有这些高级编程语言中的任何一种都翻译成所有这些汇编语言中的任何一种(对应于不同的架构)。一种方法是创建一个大量不同的翻译器,可以从每种语言翻译到每种汇编语言。

Diagram showing programming languages C, C++, and Rust on the left and assembly languages x86 and ARM on the right, with arrows between every combination

这将非常低效。为了解决这个问题,大多数编译器至少在两者之间设置了一层。编译器将使用这种高级编程语言,并将其翻译成不是那么高级的东西,但也无法在机器代码级别上工作。这称为中间表示 (IR)。

Diagram showing an intermediate representation between high level languages and assembly languages, with arrows going from high level programming languages to intermediate representation, and then from intermediate representation to assembly language

这意味着编译器可以接受所有这些高级语言中的任何一种,并将其翻译成一种 IR 语言。从那里,编译器的另一部分可以获取 IR 并将其编译成特定于目标架构的东西。

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

Same diagram as above, with labels for front-end and back-end

结论

这就是汇编语言,以及编译器如何将高级编程语言翻译成汇编语言。在 下一篇文章 中,我们将了解 WebAssembly 如何融入其中。

关于 Lin Clark

Lin 在 Mozilla 的高级开发部门工作,专注于 Rust 和 WebAssembly。

更多 Lin Clark 的文章...


6 条评论

  1. Deep Pulusani

    这些文章和插图真的很棒。干得好!

    2017 年 3 月 1 日 上午 9:45

  2. Fernando Chavez Gomes da Silva

    这是我找到的最容易理解汇编语言的方式。很棒的工作,插图也很棒!

    2017 年 3 月 2 日 上午 10:15

  3. @hfx_ben

    这勾起了我的回忆:在我的 NEC “Trek” 中编写 Z-80 的机器代码……8KB。然后在 C=64 的 6502 上编写汇编语言。
    基础!:-)
    –@ITGeek

    2017 年 3 月 2 日 下午 12:35

  4. Luca

    嗨,我认为你在谈论汇编语言部分时将 RAM 和寄存器调换了。

    欢呼 Luca

    2017 年 3 月 4 日 上午 6:19

    1. Lin Clark

      我可以肯定地告诉你,我没有将寄存器和 RAM 调换。我过去曾使用硬件描述语言从基本逻辑门设计所有这些部分(寄存器、ALU、CPU 和 RAM)。我已经使用这些部分来创建工作计算机的设计。

      此外,为了避免阅读评论的任何人感到困惑,该图并不旨在显示汇编器。正如维基百科所定义的那样,汇编器是一种“将汇编语言翻译成目标文件或机器语言格式的计算机程序”。在编译期间会使用汇编器来生成机器代码指令,但它不是此处描述或图示的一部分。

      2017 年 3 月 4 日 上午 6:39

  5. Pablo Barria Urenda

    喜欢这些文章!谢谢!

    只是想评论一下,也许按照卡通介绍的精神,你可以提及这个介绍汇编语言的电子游戏

    http://www.zachtronics.com/tis-100/

    (除了购买了一份副本之外,我与这款游戏没有任何关联)

    2017 年 3 月 13 日 下午 7:09

本文的评论已关闭。