指令的基本格式
一条机器指令必须回答两个问题:做什么,和对谁做。于是它的格式天然只有两个字段:
操作码回答”做什么”,地址码回答”对谁做”。 4.1.3 和 4.1.4 讨论前一半怎么编码,4.2 讨论后一半怎么解释,本节讨论这两半各占多少、一共几段。
机制
三个”字长”必须分清
这是本节最容易被混过去、又最常在计算题里当条件用的一组概念:
| 名称 | 定义 | 由谁决定 | 对应 |
|---|---|---|---|
| 机器字长 | CPU 一次能处理的二进制位数 | ALU 宽度 = 通用寄存器位数 | —— |
| 存储字长 | 一个存储单元的位数 | 主存的编址单位 | MDR 的位数,见 3.2.3 |
| 指令字长 | 一条指令的总位数 | 指令格式设计 | IR(指令寄存器)的位数,见 5.1.3 |
三者互相独立,可以两两不等。 但有一条工程约束几乎总成立:
按地址码个数分类
地址码字段可以有 0~4 段。每减少一个地址,就必须有一个”隐含约定”补上它——这是理解这套分类的钥匙。
| 格式 | 形式 | 完成的操作 | 少掉的地址靠什么补 |
|---|---|---|---|
| 四地址 | OP A1 A2 A3 A4 | —— | |
| 三地址 | OP A1 A2 A3 | 下条指令地址由 PC 隐含 | |
| 二地址 | OP A1 A2 | 结果隐含写回 | |
| 一地址 | OP A1 | 另一个操作数和结果都隐含在 ACC | |
| 零地址 | OP | 空操作 / 停机 / 堆栈运算 | 操作数隐含在栈顶(或根本不需要操作数) |
四地址是纯理论格式,现实中不存在,它存在的唯一意义是让你看清:PC 的发明就是把第四个地址省掉。 顺序执行这条约定,本身就是一次”用隐含换空间”。
访存次数模板
这是本节唯一的计算题类型,必须能条件反射。 前提:指令字长 = 存储字长(取指 1 次),操作数全在主存。
| 格式 | 取指 | 取操作数 | 存结果 | 合计访存 |
|---|---|---|---|---|
| 四地址 | 1 | 2 | 1 | 4 |
| 三地址 | 1 | 2 | 1 | 4 |
| 二地址 | 1 | 2 | 1 | 4 |
| 一地址(ACC 型) | 1 | 1 | 0(存 ACC) | 2 |
| 零地址 | 1 | 0 | 0 | 1 |
三条改动这张表的条件,题目一给就必须改:
- 指令字长 ≠ 存储字长 → 取指那一栏改成
。指 令 字 长 存 储 字 长 - 操作数在寄存器里 → 该次访存直接删掉。这正是 RISC 的 Load/Store 结构做的事,见 4.4.2。
- 寻址方式不是直接寻址 → 间接寻址每多一级就多一次访存。完整的访存次数模板在 4.2.2。
一地址指令有两种,访存次数不同,这是最常见的失分点:
- 双操作数型:
ADD A,即 ——访存 2 次(取指 1 + 取数 1) - 单操作数型:
INC A,即 ——访存 3 次(取指 1 + 取数 1 + 存回 1)
操作码和地址码怎么分配位数
设指令字长
- 操作码要够用:
位定长操作码最多编码 条指令(4.1.3) - 地址码要够长:
位地址字段最多直接寻址 个单元
指令字长有限时,这两件事互相抢位——整个 4.1 后半段(定长操作码、扩展操作码、各种寻址方式)都是在这场争夺里想办法。 记住这句,4.1.3、4.1.4、4.2.2 三节就串成了一条线。
当地址码不够长时,出路只有一条:不再让地址字段直接装地址,而让它装”算地址的原料”。 这正是寻址方式存在的根本理由——形式地址
定长指令字与变长指令字
| 定长指令字 | 变长指令字 | |
|---|---|---|
| 所有指令长度 | 相同 | 按需不同 |
| 代码密度 | 低(短指令被撑长) | 高 |
| 取指 | 一次定量,PC 增量是常数 | 取多长事先不知道 |
| 译码 | 字段位置固定,可与取指并行 | 必须先译一部分才知道边界 |
| 典型 | RISC(MIPS、RISC-V 全 32 位) | CISC(x86 指令 1~15 字节) |
层次辨析:定长指令字 ≠ 定长操作码
这两个”定长”说的是指令的不同部分,可以自由组合,是本章最容易看串的一对名词。
定长操作码 变长(扩展)操作码 定长指令字 MIPS:32 位指令,6 位 OP x86 的部分子集;教材的扩展操作码例题几乎全在这一格 变长指令字 少见 x86 完整形态 教材 4.1.3 / 4.1.4 讨论的全是”指令字定长、操作码定不定长”这一维,与指令字本身长不长无关。看到”某机指令字长固定 16 位,采用扩展操作码”不要觉得矛盾——那正是最标准的题设。
边界
“地址码”里放的不一定是主存地址。 它可以是寄存器编号、立即数、位移量、甚至是端口号。“地址码字段”是位置概念,“它表示什么”由操作码和寻址方式共同决定。 一个 5 位字段在 ADD R1, R2 里是寄存器号,在 ADD A 里是主存地址的一部分——同一段位置,两种含义,这就是为什么必须先译操作码。
二地址指令的结果覆盖 SUB A, B 之后 MOV 一次的原因。
零地址指令有两类,性质完全不同:一类是真的不需要操作数(NOP、HLT),一类是操作数隐含在堆栈(堆栈机的 ADD 弹两个压一个)。后者访存次数远不止 1 次——若题目提”堆栈机”,取操作数是要访存的。
指令字长是存储字长的整数倍,这是约束不是定理。 半字长指令(
操作码位数
对照速查
| 字长 | 是什么 | 常见等式 |
|---|---|---|
| 机器字长 | CPU 一次处理的位数 | = 通用寄存器位数 = ALU 宽度 |
| 存储字长 | 一个存储单元的位数 | = MDR 位数 |
| 指令字长 | 一条指令的位数 | = |
| 判断 | 对错 |
|---|---|
| 指令字长一定等于机器字长 | ❌ |
| 指令字长一定是存储字长的整数倍 | ❌(可以是 |
| 取指访存次数 = 指令字长 / 存储字长 | ✅ |
| 单字长指令 = 指令字长等于机器字长 | ❌(是存储字长) |
| 二地址指令执行后 | ❌(被结果覆盖) |
| 零地址指令一定不访问操作数 | ❌(堆栈机要访存) |
| 一地址指令一律访存 2 次 | ❌(读改写型是 3 次) |
| 定长指令字必然配定长操作码 | ❌(两个维度独立) |
| 格式 | 操作数来源 | 结果去向 | 访存(直接寻址、单字长) |
|---|---|---|---|
| 三地址 | 4 | ||
| 二地址 | 4 | ||
| 一地址(双操作数) | ACC, | ACC | 2 |
| 一地址(单操作数) | 3 | ||
| 零地址(NOP/HLT) | 无 | 无 | 1 |
考点
- 指令 = 操作码 + 地址码;四地址是理论格式,PC 就是省掉的第四个地址
- 机器字长 / 存储字长 / 指令字长三者独立,存储字长 = MDR 位数
- 取指访存次数 = 指令字长 ÷ 存储字长
- 访存次数:三/二地址 4 次,一地址 2 次(读改写 3 次),零地址 1 次
- 二地址指令的结果覆盖第一个操作数
- 地址字段位数
;操作码与地址码在有限指令字长内互相挤压 - 定长指令字与定长操作码是两个维度,可自由组合
- 地址码字段里可以放寄存器号、立即数、位移量,不一定是主存地址
链接
- 🏠 返回总览:计算机组成原理第 4 章:指令系统总览
- ⬅️ 上一节:4.1.1 指令集体系结构
- ➡️ 下一节:4.1.3 定长操作码指令格式
- 🔗 3.2.3 主存储器的基本组成(存储字长与 MDR)
- 🔗 4.2.2 常见的数据寻址方式(形式地址与有效地址分家)
- 🔗 5.3 指令执行过程(本地资料)(取指的数据流)
- 📖 名词库:第 4 章名词库