将处理组织成阶段
2022-08-18 本文已影响0人
Sun东辉
通常,处理一条指令包括很多操作。将它们组织成某个特殊的阶段序列,即使指令的动作差异很大,但所有的指令都遵循统一的序列。每一步的具体处理取决于正在执行的指令。创建这样一个框架,我们就能够设计一个充分利用硬件的处理器。下面是关于各个阶段以及各阶段内执行操作的简略描述:
- 取指(fetch):取指阶段从内存读取指令字节,地址为程序计数器 (PC) 的值。从指令中抽取出指令指示符字节的两个四位部分,称为 icode(指令代码)和 ifun(指令功能)。它可能取出一个寄存器指示符字节,指明一个或两个寄存器操作数指示符 rA 和 rB。它还可能取出一个四字节常数字 valC 。它按顺序方式计算当前指令的下一条指令的地址 valP。也就是说, valP 等于 PC 的值加上已取出指令的长度。
- 译码(decode):译码阶段从寄存器文件读入最多两个操作数,得到值 valA 和/或 valB,通常,它读入指令 rA 和 rB 字段指明的寄存器,不过有些指令是读寄存器 %rsp 的。
- 执行(execute):在执行阶段,算术/逻辑单元 (ALU) 要么执行指令指明的操作(根据 ifun 的值),计算内存引用的有效地址,要么增加或减少栈指针。得到的值我们称为 valE 。在此,也可能设置条件码。对一条条件传送指令来说,这个阶段会检验条件码和传送条件(由 ifun 给出),如果条件成立,则更新目标寄存器。同样,对一条跳转指令来说,这个阶段会决定是不是应该选择分支。
- 访存(memory):访存阶段可以将数据写入内存,或者从内存读出数据。读出的值为 valM。
- 写回(write back): 写回阶段最多可以写两个结果到寄存器文件。
- 更新 PC(PC update):PC 设置成下一条指令的地址。
处理器无限循环,执行这些阶段。在我们简化的实现中,发生任何异常时,处理器就会停止:它执行 halt 指令或非法指令,或它试图读或者写非法地址。在更完整的设计中,处理器会进入异常处理模式,开始执行由异常的类型决定的特殊代码。
从前面的讲述可以看出,执行一条指令是需要进行很多处理的。我们不仅必须执行指令所表明的操作,还必须计算地址、更新栈指针,以及确定下一条指令的地址。幸好每条指令的整个流程都比较相似。因为我们想使硬件数量尽可能少,并且最终将把它映射到一个二维的集成电路芯片的表面,在设计硬件时,一个非常简单而一致的结构是非常重要的。降低复杂度的一种方法是让不同的指令共享尽量多的硬件。例如,我们的每个处理器设计都只含有一个算术/逻辑单元,根据所执行的指令类型的不同,它的使用方式也不同。在硬件上复制逻辑块的成本比软件中有重复代码的成本大得多。而且在硬件系统中处理许多特殊情况和特性要比用软件来处理困难得多。