指令的基本格式

一条机器指令必须回答两个问题:做什么,和对谁做。于是它的格式天然只有两个字段:

(操作码)(地址码)

操作码回答”做什么”,地址码回答”对谁做”。 4.1.3 和 4.1.4 讨论前一半怎么编码,4.2 讨论后一半怎么解释,本节讨论这两半各占多少、一共几段。

机制

三个”字长”必须分清

这是本节最容易被混过去、又最常在计算题里当条件用的一组概念:

名称定义由谁决定对应
机器字长CPU 一次能处理的二进制位数ALU 宽度 = 通用寄存器位数——
存储字长一个存储单元的位数主存的编址单位MDR 的位数,见 3.2.3
指令字长一条指令的总位数指令格式设计IR(指令寄存器)的位数,见 5.1.3

三者互相独立,可以两两不等。 但有一条工程约束几乎总成立:指令字长存储字长因为指令必须整存整取。由此得到取指的访存次数:取一条指令的访存次数指令字长存储字长按 的取值给指令起名: 叫单字长指令, 叫双字长指令, 叫半字长指令。这三个名字都是相对存储字长说的,不是相对机器字长。 题目若说”某机指令字长与机器字长相等,均为 32 位,存储字长 16 位”,那么取一条指令要访存 2 次,不是 1 次。

按地址码个数分类

地址码字段可以有 0~4 段。每减少一个地址,就必须有一个”隐含约定”补上它——这是理解这套分类的钥匙。

格式形式完成的操作少掉的地址靠什么补
四地址OP A1 A2 A3 A4,下条指令地址 ——
三地址OP A1 A2 A3下条指令地址由 PC 隐含
二地址OP A1 A2结果隐含写回 (目的操作数被覆盖)
一地址OP A1另一个操作数和结果都隐含在 ACC
零地址OP空操作 / 停机 / 堆栈运算操作数隐含在栈顶(或根本不需要操作数)

四地址是纯理论格式,现实中不存在,它存在的唯一意义是让你看清:PC 的发明就是把第四个地址省掉。 顺序执行这条约定,本身就是一次”用隐含换空间”。

访存次数模板

这是本节唯一的计算题类型,必须能条件反射。 前提:指令字长 = 存储字长(取指 1 次),操作数全在主存。

格式取指取操作数存结果合计访存
四地址1214
三地址1214
二地址1214
一地址(ACC 型)110(存 ACC)2
零地址1001

三条改动这张表的条件,题目一给就必须改:

  1. 指令字长 ≠ 存储字长 → 取指那一栏改成 指令字长存储字长。
  2. 操作数在寄存器里 → 该次访存直接删掉。这正是 RISC 的 Load/Store 结构做的事,见 4.4.2。
  3. 寻址方式不是直接寻址 → 间接寻址每多一级就多一次访存。完整的访存次数模板在 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 三节就串成了一条线。

当地址码不够长时,出路只有一条:不再让地址字段直接装地址,而让它装”算地址的原料”。 这正是寻址方式存在的根本理由——形式地址 与有效地址 EA 从此分家。

定长指令字与变长指令字

定长指令字变长指令字
所有指令长度相同按需不同
代码密度低(短指令被撑长)高
取指一次定量,PC 增量是常数取多长事先不知道
译码字段位置固定,可与取指并行必须先译一部分才知道边界
典型RISC(MIPS、RISC-V 全 32 位)CISC(x86 指令 1~15 字节)

层次辨析:定长指令字 ≠ 定长操作码

这两个”定长”说的是指令的不同部分,可以自由组合,是本章最容易看串的一对名词。

定长操作码变长(扩展)操作码
定长指令字MIPS:32 位指令,6 位 OPx86 的部分子集;教材的扩展操作码例题几乎全在这一格
变长指令字少见x86 完整形态

教材 4.1.3 / 4.1.4 讨论的全是”指令字定长、操作码定不定长”这一维,与指令字本身长不长无关。看到”某机指令字长固定 16 位,采用扩展操作码”不要觉得矛盾——那正是最标准的题设。

边界

“地址码”里放的不一定是主存地址。 它可以是寄存器编号、立即数、位移量、甚至是端口号。“地址码字段”是位置概念,“它表示什么”由操作码和寻址方式共同决定。 一个 5 位字段在 ADD R1, R2 里是寄存器号,在 ADD A 里是主存地址的一部分——同一段位置,两种含义,这就是为什么必须先译操作码。

二地址指令的结果覆盖 ,这是格式定义的一部分,不是实现细节。 所以 SUB A, B 之后 的原值没了。这一条在写指令序列的题里必须记住,也是二地址机器常常要先 MOV 一次的原因。

零地址指令有两类,性质完全不同:一类是真的不需要操作数(NOP、HLT),一类是操作数隐含在堆栈(堆栈机的 ADD 弹两个压一个)。后者访存次数远不止 1 次——若题目提”堆栈机”,取操作数是要访存的。

指令字长是存储字长的整数倍,这是约束不是定理。 半字长指令()真实存在,此时一次访存取回两条指令,这不仅合法而且是代码密度优化的常规手段。做题时看清题目给的是哪一种。

操作码位数 与”能编码多少条指令”的关系只在定长操作码下是 。 扩展操作码下这个上界不成立,见 4.1.4。

对照速查

字长是什么常见等式
机器字长CPU 一次处理的位数= 通用寄存器位数 = ALU 宽度
存储字长一个存储单元的位数= MDR 位数
指令字长一条指令的位数= 存储字长
判断对错
指令字长一定等于机器字长❌
指令字长一定是存储字长的整数倍❌(可以是 )
取指访存次数 = 指令字长 / 存储字长✅
单字长指令 = 指令字长等于机器字长❌(是存储字长)
二地址指令执行后 的原值保留❌(被结果覆盖)
零地址指令一定不访问操作数❌(堆栈机要访存)
一地址指令一律访存 2 次❌(读改写型是 3 次)
定长指令字必然配定长操作码❌(两个维度独立)
格式操作数来源结果去向访存(直接寻址、单字长)
三地址4
二地址4
一地址(双操作数)ACC, ACC2
一地址(单操作数)3
零地址(NOP/HLT)无无1

考点

  • 指令 = 操作码 + 地址码;四地址是理论格式,PC 就是省掉的第四个地址
  • 机器字长 / 存储字长 / 指令字长三者独立,存储字长 = MDR 位数
  • 取指访存次数 = 指令字长 ÷ 存储字长
  • 访存次数:三/二地址 4 次,一地址 2 次(读改写 3 次),零地址 1 次
  • 二地址指令的结果覆盖第一个操作数
  • 地址字段位数 ;操作码与地址码在有限指令字长内互相挤压
  • 定长指令字与定长操作码是两个维度,可自由组合
  • 地址码字段里可以放寄存器号、立即数、位移量,不一定是主存地址

链接