# 5. 计算模型与机器语言

在前面章节中我们深入底层，详细讨论了计算机的计算单元与存储单元的构造方式，这一节我们将视野提升一个抽象层次，来看一下通过这些组件构建起来的最基础的计算机模型，并简单讨论一下为该模型设计指令集所需要考虑的因素。

到目前为止，我们讨论的内容局限于两个芯片：

* CPU: 计算芯片，前文提到的ALU、寄存器都是CPU的组成部分，除此之外CPU还至少需要一个控制组件（Control Unit），用来“指挥”CPU的工作
* 内存: 存储芯片，CPU 所执行的指令以及操作的数据都存储在内存中

CPU 与内存通过总线（Bus）进行通信，总线上包含三种信号：地址信号、数据信号、控制信号。如下图所示：

![](https://4257267501-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MdQXCtxb9g6w1DURwQ9%2F-MdWKlKNQdKW9dQ6SVSt%2F-MdWT_NInQ1npcJjz_Yu%2Fcpu_arch.png?alt=media\&token=f75d04dc-1d34-41df-ab5a-fadef6651f0f)

虽然该图很简单，但已经呈现出了一个最基本的计算模型：在 CU(Control Unit) 的控制下，CPU 反复地执行存放在内存中的指令，指令的执行效果就是将内存或寄存器中的数据扔进 ALU 做运算，再将结果写回内存或寄存器。至于CPU来回倒腾这些数据到底是为了什么，这是宏观的层面上所具备的意义，可能是在完成一个交易、可能是在模拟一个电子游戏、也可能是在播放一部电影。但不管是什么事情，在微观层面的体现都是这样。

> 如果读者熟悉图灵机模型，会发现上文所说的计算模型就是图灵机的一种映射。事实上如果我们再加上输入与输出设备，就是一个冯诺伊曼架构的计算机模型。

CPU 执行指令通常划分成多个阶段：取指、解码、执行、存储，一个完整的循环被称为 CPU 的一个执行周期。整个流程由 CU 主导，CPU 的各个组件会在一起密切配合，例如寄存器 PC(Program Counter) 总是保存着下一条指令的内存地址，PC 的内容由当前执行的指令决定；如果需要 ALU 参与运算，CU 在解码后需要将各种输入信号传给 ALU。这些逻辑需要非常复杂的硬件电路来支撑，但这里我们不再深入讨论硬件实现，而是将其看着是一个功能完善的整体。

在该模型下，我们需要如下几类指令：

1. 算术、逻辑运算。该工作通过 ALU 来完成，输入、输出来自寄存器或者内存
2. 数据传输。将数据在寄存器与内存之间传输
3. 流程控制。如何获取并执行下一条指令，程序默认是顺序执行的，我们还要考虑如何完成条件判断以及完成程序跳转等

设计指令集时需要考虑如下因素：

1. 内存模型 \
   既然 CPU 的毕生精力都在倒腾内存中的数据，那么如何对内存进行寻址是指令集的重点。内存模型决定了寻址方式，以及能够寻址的内存空间大小。例如上文中提到的 Intel 8086 芯片，其为了在16位寄存器中支持20位的地址空间，采用的是分段寻址（Segmented Addressing）模式。
2. 指令格式
3. 寄存器种类 \
   哪些寄存器是专用寄存器，哪些是通用寄存器。例如 Intel 8086 芯片中，为了支持分段寻址，专门设计了段寄存器（Segment Registers）与索引寄存器（Index Registers）。

其中最重要的是内存模型，内存模型会显著影响上层程序的设计，例如操作系统的实现。事实上内存地址的用途是多样化的，不仅仅局限在对内存芯片的寻址上，如果我们重新审视 CPU 与内存的关系，会发现 CPU 根本不知道存储芯片的存在，CPU 面对的只是一个个具备存储能力的地址而已，如果使用高级程序设计的词汇来描述，内存地址就是一个接口，而内存芯片是其中的一种实现；其它的实现例如 [Memory-mapped IO](https://en.wikipedia.org/wiki/Memory-mapped_I/O) 将内存地址映射成 I/O 设备，而 [Memory-mapped File](https://en.wikipedia.org/wiki/Memory-mapped_file) 将一段内存地址空间映射成磁盘上的文件的某一段内容，这样 CPU 就能够像操作内存一样操作 I/O 设备以及文件了。

指令集是 CPU 全部功能的描述，是面向 CPU 进行编程的唯一媒介，所以也叫着机器语言，机器语言是抽象层次最低的编程语言，用二进制表示，其中每个0与1都可以想象成某个精灵在拨动逻辑门中的电路开关，以便让电子信号以预设的轨迹流过整个电路。机器语言是硬件到软件的过渡，从更深刻的意义上看，机器语言刻画的是一个计算模型，而如何合理、高效地使用该计算模型来解决现实之中的问题，我们还需要专门的系统来进行管理与协调，并提供更高层次的抽象模型，这个系统就是操作系统。
