汇编小册(三) 指令周期

本文最后更新于10 个月前,文中所描述的信息可能已发生改变。

我们通过指令来要求 CPU 去做某事。假设我们给出一个指令:嘿,CPU,你能把这两个数字加在一起吗?当 CPU 准备好处理该指令时,它会启动一个包含 3 个主要阶段的循环:

  1. Fetch:从内存中获取数据
  2. Decode:解码该数据,获得指令
  3. Execute:执行指令

Fetch 获取

在第一阶段,CPU 必须从内存中获取指令数据,这样 CPU 才可以看到你要求它做什么。

内存,也称为随机存取内存或 RAM,是你的计算机拥有的一种短期存储。而有长期的存储位置,例如磁盘。但是当我们需要暂时保留某些东西时,或者需要更快的访问响应速度时,我们会使用内存。

发挥我们的想象力,把 CPU 看作是一个仓库。CPU 访问你的内存时,有点像去装有箱子的货架。每个箱子(数据)都有一个位置(内存地址),你可以在其中查看箱子内的内容(读取该内存地址处的数据)。你还可以将所有内容从箱子里拿出来(清除该内存地址处的内容),然后将新内容放入箱子中(在该内存地址存储新数据)。

在内存中,所有数据都以电的形式存储(这里我有一个疯狂的想法,CPU 好像一名能够控制雷电的法师)。因为我们将数据存储为电,所以当你的计算机关闭后,并且不再有电流向它时,你存储的所有内容都会被清除!这有点像每天晚上仓库关闭时,所有的包裹都被扔掉了。这就是为什么我们将其称为短期记忆,我们将重要的东西存储在磁盘中,这是我们的长期存储,以免被丢弃。

我们的大货架(内存)有非常大的空间,来存放我们的箱子。但是在仓库中移动大箱子可能又慢又麻烦。因此,为了更快和临时的存储,我们在仓库安装了一组有编号的小货架,我们可以在其中放置较小的箱子。这个小货架,就是我们 CPU 的寄存器。

寄存器是 CPU 可以存储小块数据的地方。假如我们需要将两个数字相加。

首先,CPU 检索等式所需的第一个数字。由于 CPU 一次只能做一件事,因此它需要放下第一个数字才能抓取下一个数字。因此,它暂时将第一个数字存储到寄存器中。

接下来,CPU 获取等式中的第二个数字。CPU 现在拥有将两个数字相加所需的所有信息。它继续执行相加的指令,输出新数组,即相加的结果,然后继续从内存中获取数据。

现在你可能会问,既然寄存器更快,为什么我们不将所有内容都存储在寄存器中,而还要存在内存中呢?我们寄存器的空间是有限的。实际大小取决于计算机的硬件。你可能会获得大约 16 个通用寄存器来存储你的数据。但有些寄存器只能在内部使用,不能直接访问。

内存可以轻松容纳超过寄存器容量的 1500 万倍!由于计算机必须处理如此多的数据,因此我们的寄存器很快就会耗尽空间。因此,任何我们不需要用于指令的数据,我们都会放在内存中。

Decode 解码

现在我们已经获取了数据,那这些数据实际上是什么样子的?

我们之前提到过,计算机只能读取数字。因此,我们存储的所有数据都必须以计算机可以读取的方式表示。

这些数字所代表的内容包括五大类:

  • 指令
  • 数值
  • 字母
  • 寄存器
  • 内存地址

当指令周期到达解码步骤时,CPU 将识别它正在查看的数据类型。

每个 CPU 都有一组物理内置在芯片中的指令,你可以将其视为与 CPU 可以执行的数字的操作列表。因为从 Fetch 获取阶段获取的数据只是数字,所以 CPU 可以将其看到的数字与设置的指令列表进行比较来解码指令。

数值指令
1add
2sub

解码获取的数据,第一部分是操作码,它是 CPU 可以运行的操作的唯一标识符。在将两个数字相加的情况下,该操作码就是 add 。

获取的下一个数字是要执行的参数。举一个假设的例子,假设我们有一个这样的指令:

add 3, 4

我们的操作码是 add,我们的参数是 3 和 4 。

Execute 执行

在获取的数据被解码后,CPU 得到一个可以执行的指令。

如果指令是算术的(如加法或减法)或逻辑指令(如比较两位数以给出真或假),则有一个额外的步骤在算术逻辑单元或 ALU 处。这个单位负责做数学运算。完成数学运算后,ALU 将返回一个值,该值存储在寄存器中,直到指令需要它。

汇编小册(四) 指令映射到机器代码
汇编小册(二) 嘿!CPU!我要去北京