3.2 CPU中的核心部件与Simple-MIPS指令(1)
阅读入口
各部件的职责
程序计数器PC
PC存储下一条要执行的指令的内存地址。可以把它想成读书时的书签,标记下一次从哪里继续。顺序执行时,它在取指后增加4:一条Simple-MIPS指令是32位,即4字节,下一条指令正好在相邻的4字节之后。分支和跳转指令会直接改写PC,顺序执行、循环和条件分支都靠这一点实现。
PC只负责提供地址,不判断该地址上是什么内容;取回指令之后的工作由IR和控制单元接手。
指令寄存器IR
取指时,内存按PC给出的地址送回32位指令,这条指令先放进IR,再由控制单元译码并发出执行信号。IR只保存当前这一条指令,取下一条时会覆盖它的内容。
一条Simple-MIPS指令的32位通常划分为几个字段:
- 操作码:指出指令类型,例如加载、存储、减法;
- 寄存器编号:指出源寄存器和目标寄存器;
- 立即数或地址偏移:供内存访问或算术运算使用的常数。
算术逻辑单元ALU
ALU是执行运算的部件,通常接收两个操作数,输出一个结果。它处理的运算包括:
- 算术运算:加、减、乘、除;
- 逻辑运算:与、或、非、异或;
- 移位运算:左移、右移,包含逻辑移位和算术移位;
- 比较运算:比较两个数的大小,设置条件标志。
执行哪一种运算由控制单元根据操作码决定。ALU本身不区分当前是哪条指令,它只对送进来的操作数执行被指定的运算。
寄存器组
寄存器是CPU内部的高速存储单元,用来临时存放数据和地址。它的访问通常在1个时钟周期内完成,比内存快得多;数量有限,Simple-MIPS有32个通用寄存器;每个寄存器固定32位。
寄存器按用途有习惯命名:
| 寄存器 | 用途 |
|---|---|
$zero | 恒为0 |
$at | 汇编器临时使用 |
$v0–$v1 | 函数返回值 |
$a0–$a3 | 函数参数 |
$t0–$t9 | 临时寄存器 |
$s0–$s7 | 需要跨调用保留的寄存器 |
$zero的值由硬件固定,写入也会被丢弃,因此常用来提供常数0。以上是常见命名,完整编号共32个;寄存器编号如何出现在指令里,见Simple-MIPS教学指令集。
一条指令的取指与执行
- PC把地址送到内存,内存返回该地址上的32位指令;顺序执行时PC同时增加4。
- 指令进入IR,控制单元按操作码译码,确定要读哪些寄存器、做什么运算、是否访问内存。
- 寄存器组把操作数送入ALU,ALU完成运算;如果指令是load或store,还要由内存完成读写。
- 结果写回寄存器组,PC已经指向下一条指令。
读这几段时先记每个部件保存什么:PC存地址,IR存当前这条指令,寄存器组给ALU送数。有了这张对照表,下面读指令的写法就不必来回翻页。
操作数与指令形式
Simple-MIPS是为教学目的设计的简化指令集。它参考MIPS等真实架构,但并不完全等同于真实的MIPS指令集,目的是更直观地讲解计算机组成原理的核心概念。本页的指令都按Simple-MIPS的写法给出;PC、IR、ALU和寄存器组如何配合执行这些指令,见CPU的核心部件。
每条Simple-MIPS指令固定32位,每个通用寄存器也固定32位。常见指令的基本形式是
操作码 目标, 源1, 源2操作数按角色分为以下几类:
| 记号 | 含义 |
|---|---|
$rd | 目标寄存器,结果写在这里 |
$rs | 第一个源寄存器;访存时兼作基址寄存器 |
$rt | 第二个源寄存器;在load/store中承担另一角色 |
offset | 立即数偏移,与 $rs中的地址相加 |
shamt | 移位位数,取0–31 |
label | 标签,代表一条指令的地址 |
寄存器编号的具体分工($zero、$t0–$t9、$s0–$s7等)由寄存器组的约定决定,不在指令本身的语义里体现。
操作码 目标, 源1, 源2是本节所有指令的共同形式,$rd、$rs、$rt的角色由这张表固定。3.3的控制流指令继续使用同一套记号,两节可以对照着读。
学习安排
教材先拆开CPU的内部部件,再引入指令,因为读一条指令时必须知道每个操作数落在哪个部件:PC提供地址,IR暂存指令,寄存器组给ALU送数,load/store把寄存器与内存连起来。按这个顺序读,部件表不是要背的清单,而是读指令时的对照表。
- 3.2只讲数据传送、算术和移位指令,控制流指令留到3.3;两节合起来才能写出循环。
- 教材的示例主要用
$t0、$t1、$t2和$s1;读例子时先认寄存器编号,再看操作码。 - 本节聚焦汇编写法和每条指令的语义;指令字段的划分回到CPU部件页对照即可。
课程约定
- Simple-MIPS是教学指令集,名称与真实MIPS有差异:教学集写
mov、shiftl、shiftr,标准汇编分别写move、sll、srl。作业按题目采用的指令集作答。 - 访存一律写成
offset($rs),读题时先分清哪一个是基址、哪一个是偏移,不要漏掉括号。 - PC和地址都按字节计:一条指令4字节,顺序执行时下一条是当前地址加4,不要写成加1。
易错点
- 真实MIPS没有独立的
mov,但Simple-MIPS把复制当作基本指令;不要把“真实MIPS没有”当成“Simple-MIPS不能用”。 - 逻辑右移
srl左侧补0,只有对非负整数才等同于除以 后向下取整;不要拿它处理带符号数的除法。 sll、srl的shamt取0–31。
读指令的检查顺序
拿到一条指令,先看它是否访问内存:lw和sw读写内存,其余指令只改寄存器或PC。再看三个寄存器分别站在rd、rs、rt的哪个位置,最后才代数值计算。这个顺序能避免把rs和rt的角色对调。