Appearance
指令系统的基本概念
2026 大纲 四(一)指令系统的基本概念。
指令字里明明少了一项,程序却照样往下走
按存储程序的工作方式推一遍:CPU 执行完一条指令,必须知道做什么、对谁做、结果放哪、下一条在哪。四项缺一不可。可是翻开任何一台真实机器的指令格式,第四项——下条指令地址——都不在指令字里。
它被 PC 的计数功能吸收了。程序顺序存放、顺序执行,所以下条指令的地址是可以算出来的:PC 加上本条指令的长度即可,硬件自动完成,指令一个字段都不用出。只有需要打破这个顺序时,转移指令才把目标地址写进来。这等于用一个寄存器,换掉了每条指令里的一整个地址字段——本篇后面那条"地址码个数越少、隐含约定越多"的取舍链,第一环就在这里。
顺着同一条思路往下推,还能省:结果地址和源地址共用一个字段,三地址就变成二地址;把一个操作数固定在累加器里,二地址就变成一地址;把操作数全都放在栈顶,一地址就变成零地址。每减掉一个地址字段,指令都变短了,但信息一点没少——它只是从指令字挪进了硬件的隐含约定里。 代价则是灵活性:二地址指令写结果时必然覆盖掉第一个源操作数,因为那本来就是同一个字段。
这条链贯穿全篇。还有一件事需要先立起来:哪些东西属于 ISA、哪些属于微架构。判据只有一句——换一款实现同一 ISA 的处理器,它会不会变? 不变的属 ISA(否则老程序换台机器就跑不了),会变的属微架构。这一句话本身就是近年真题反复出的考点。
交互可视化
一、一条指令必须携带哪些信息
从冯·诺依曼结构的"存储程序"工作方式出发,可以推出一条指令必须明显或隐含地包含四项信息:
| 必须说清的事 | 为什么必须有 |
|---|---|
| 操作码 | 不说做什么,硬件无从产生控制信号 |
| 源操作数或其地址 | 不说操作谁,运算部件拿不到输入 |
| 结果的地址 | 不说结果放哪,算完就丢了 |
| 下条指令地址 | 程序要能自动往下走 |
第四项是关键的一处设计取舍。如果每条指令都显式写出下条指令地址,指令会长得离谱——而绝大多数指令后面跟的就是紧挨着的那一条。于是硬件替它记账:程序计数器 PC 既存放指令地址,又具备计数功能。早期确实存在四地址指令,第四个地址就是下条指令地址;PC 的引入把这一整个字段从每条指令里省掉了。PC 在取指周期自增的时序细节见 指令执行过程。
剩下三项归并后,指令的通用结构就是两段:
二、ISA:软件能看见的那一层
一台计算机能执行的机器指令的集合称为指令集体系结构(Instruction Set Architecture,ISA),也就是指令系统——两者是同一个东西的两个名字。它是硬件与软件之间的约定界面:规定了程序员和编译器能看见、能用的一切,把"怎么实现"留给硬件设计者。
| ISA 规定(软件可见,换实现也不变) | 微架构决定(实现细节,可以随芯片改) |
|---|---|
| 指令格式与指令集 | 主频、时钟周期 |
| 通用寄存器的个数与位数 | 流水线级数、是否超标量 |
| 寻址方式 | Cache 的容量与层次 |
| 数据类型与字长 | 控制器用微程序还是硬布线 |
| 异常与中断模型 | 内部总线结构、加法器的进位方式 |
| 存储器模型(编址方式、字节序) | 数据通路是单总线还是多总线 |
这条界线解释了一件常被忽略的事:同一份 x86 可执行文件能在跨越二十年的处理器上运行,正是因为这二十年里变的全是右列。左列一动,二进制兼容立刻破裂。

图 4.5 MIPS 指令格式(R 型)
指令格式在 ISA 里是以位段划分的形式规定死的:OP 占 rs/rt/rd 各 5 位,shamt 5 位,func 6 位。寄存器号占 5 位,直接意味着这套 ISA 有
三、按地址码个数分类
地址码个数不是越多越好也不是越少越好,而是一条"显式写出"与"隐含约定"之间的连续取舍:
| 类型 | 形式 | 语义 | 省掉了什么、代价是什么 |
|---|---|---|---|
| 三地址 | 三个地址全显式给出。源操作数不被破坏、调度自由度最大,代价是指令最长 | ||
| 二地址 | 结果地址与第一源地址合并。省一个地址字段,代价是 | ||
| 一地址 | 另一源操作数与结果隐含在 ACC。单目运算不需要 ACC,双目才需要 | ||
| 零地址 | 无操作数,或操作数在栈顶 | 地址码全部消失 |
表里最后两行各有一处容易读偏。一地址指令未必要用 ACC:取反、取负、加 1 这类单目运算,那唯一的地址既是操作数地址也是结果地址,压根不需要第二个操作数,ACC 无从谈起;只有双目运算才要靠 ACC 补上缺掉的那个操作数与结果。零地址也分两种:一种是真的不碰数据(NOP、HLT),另一种是操作数隐含在栈顶(栈型机的 ADD)——"零地址"说的是指令字里没有地址字段,不等于这条指令没有操作数。
这条取舍链正好对应教材按"操作数位置怎么指定"划分的四种指令系统风格:
| 风格 | 操作数在哪 | 典型指令形态 | 代价 |
|---|---|---|---|
| 累加器型 | 一个操作数与结果恒在 ACC | 一地址 | 复杂表达式要反复进出 ACC,程序变长 |
| 栈型 | 操作数恒在栈顶 | 零地址 / 一地址 | 指令字最短,但表达式求值顺序被写死,不灵活 |
| 通用寄存器型 | 立即数、寄存器、存储单元皆可 | 二地址 / 三地址 | 指令较长,但调度灵活 |
| Load/Store 型 | 只有取数/存数指令能访存,运算全在寄存器间 | 三地址 | 指令条数变多,但长度与执行时间高度一致 |
前两种只在早期机器和虚拟机(如 Java 虚拟机)里使用;现代通用处理器基本都是后两种。Load/Store 型的"规整"正是流水线得以高效运转的前提,这条线索会在 CISC 与 RISC 里接上。
四、操作类型
| 类别 | 典型指令 | 说明 |
|---|---|---|
| 算术与逻辑运算 | ADD, SUB, CMP, MUL, DIV, AND, OR, NOT, NEG, XOR, INC, DEC | 双目与单目运算 |
| 移位 | 算术移位、逻辑移位、循环移位 | 一条指令移多位时用桶形移位器实现 |
| 数据传送 | MOV, LOAD, STORE | 寄存器之间、寄存器与存储单元之间 |
| 串操作 | 串传送、串比较、检索 | 对字符串整体操作 |
| 顺序控制 | JMP, 条件转移, CALL, RET, 跳步 | 通过把目标地址送入 PC 实现 |
| CPU 控制 | 停机、开/关中断、模式切换 | 多为特权指令,只能在内核态执行 |
| 输入输出 | IN, OUT | 统一编址时可由访存指令代劳,无须单设 |
顺序控制这一行里,转移与调用的根本区别只有一条:要不要保存返回地址。JMP 把目标地址送进 PC 就完事,一去不返;CALL 必须先把下条指令的地址存起来(压栈或存入固定单元),RET 再把它取回送进 PC。这一条也是过程调用为什么非要用栈的起点,展开见 机器级表示。输入输出那一行同样值得多看一眼:I/O 指令并非必需——端口与主存统一编址时,普通的访存指令就能读写端口,机器可以完全不设 IN/OUT。
指令系统设计要满足完备性(所提供的操作类型足以编制任何可计算的程序),另有兼容性、均匀性(一种运算能处理多种数据类型)、可扩充性(操作码要留出编码空间)三条原则。最后一条直接指向 扩展操作码 的设计。
五、指令字长、机器字长、存储字长
| 名称 | 定义 | 由什么决定 |
|---|---|---|
| 机器字长 | CPU 一次能处理的数据位数 | ALU 位宽、通用寄存器宽度 |
| 指令字长 | 一条指令的二进制长度 | 操作码长度 + 地址码长度 × 地址码个数 |
| 存储字长 | 存储器一个单元的位数 | 编址单位 |
三者可以相等,也可以互不相等。早期计算机三者相等——访问一个存储单元就恰好取出一条完整指令或一个完整数据,控制方式因而非常简单。随着数据类型增多、存储容量增大,指令字长逐渐变得可变,出现单字长、双字长指令,控制电路随之复杂化,而多字长指令要多次访存才能取出一条完整指令,反过来拖慢 CPU。因此有一条经验:把使用频度高的指令(数据传送、算术逻辑运算)设计成单字长或短字长格式,把长格式留给不常用的指令。
命名基准与取指次数是两个除数:IBM 370 与 8086 的实例(做"某双字长指令要访存几次"这类题、发现自己拿错除数时展开)
"单字长""双字长"里的那个字,指的是机器字长,不是存储字长。教材给的例子把这个基准摆得很清楚:IBM 370 的指令字长可变,有 16 位(半个字)、32 位(一个字)、48 位(一字半)三种;Intel 8086 则有 8、16、24、32、40、48 位六种。所以
而"这条指令要访存几次才取得完"是另一个问题——那要拿指令字长去除编址单位。机器字长 32 位、按字节编址时,一条双字长指令是 64 位
指令存放在按字节编址的内存里,为便于取指和地址计算,指令字长通常取 8 的整数倍;算出来不是 8 的倍数就要向上圆整,具体做法见 指令格式与扩展操作码。
考点速记
- 一条指令必须携带操作码、源操作数地址、结果地址、下条指令地址四项,第四项被 PC 的计数功能吸收,因而指令字里通常没有它。
- ISA 是软硬件的约定界面,判据是"换一款实现同一 ISA 的处理器它会不会变"——寄存器个数与位数、指令字格式、寻址方式、数据类型、字节序、异常与中断模型属 ISA;主频、流水线级数与深度、Cache 容量、控制器实现方式、数据通路结构、加法器进位方式属微架构。
- 地址码个数减少时信息没有消失,只是从指令字挪进了隐含约定(二地址共用地址、一地址靠 ACC、零地址靠栈顶),四种指令系统风格正是这条取舍链的具体化;三种字长互相独立,命名看机器字长、取指次数看编址单位。
这一节在真题里被考过的形式:
- 给四项内容,问哪些由 ISA 规定(2022-18、2025-16、2026-16 连着三年考同一件事)。做法是逐项套那一句判据。2022-18 的四项里,"指令字格式和指令类型""通用寄存器个数和位数"是软件写程序时必须知道的,属 ISA;"CPU 的时钟周期""加法器的进位方式"换个实现就变,属微架构。2025-16 四个选项中只有"是否采用定长指令字格式"是软件看得见的,阵列乘法器、微程序控制器、单总线数据通路全是实现细节。2026-16 反过来问哪个不是——超级流水线是流水线深度的实现选择,属微架构;而虚拟存储管理方式、向量中断、I/O 指令都要写进程序或影响程序行为,属 ISA。⚠️ 最容易被误判的是虚拟存储管理方式与中断响应方式:它们听起来"很硬件",但操作系统必须按约定去写页表、写中断向量表,所以在 ISA 一侧。
- 给出指令格式的位段划分,反推出几项软件可见规格(2010-43、2015-44)。这类题第一问几乎固定是"最多可定义多少条指令 / 最多有多少个通用寄存器 / MAR 与 MDR 至少各要多少位",全部由字段位宽直接读出:
位操作码 最多 条指令, 位寄存器号 最多 个通用寄存器。MAR 的位数由地址空间与编址单位共同决定——2010-43 里主存 128KB 而按字编址、字长 16 位,故单元数 ,MAR 是 16 位而不是 17 位;MDR 的位数则等于存储字长 16 位。这一步拿错编址单位,后面全错。 - 由指令格式定义反推指令条数的上限(2015-44)。该机 7 位操作码,但三地址、二地址、单地址三种格式靠"末 3 位是否全 0""末 6 位是否全 0"区分,而不是靠操作码扩展,所以三种格式共用同一个 7 位操作码空间,最多
条。这里要看清题面用什么来区分格式——是操作码前缀,还是地址字段的取值。
易错:把"下条指令地址"当成指令字里不存在的信息。它存在,只是被 PC 的计数功能吸收了;转移指令仍要显式给出。
易错:认为地址码越少能力越弱。信息只是挪进了隐含约定,代价是灵活性(二地址会覆盖第一个源操作数),不是算不出来。
易错:把 Cache 容量、流水线级数、控制器实现方式算进 ISA。判据是"换一款实现同一 ISA 的处理器它会不会变"。
易错:算 MAR 位数时直接拿主存字节数取对数。按字编址时要先除以字的字节数,得到的是单元数。
易错:把"单字长指令"里的字当成存储字长。命名基准是机器字长;取指访存几次才看编址单位。
教材出处
- 袁春风《计算机组成与系统结构(第 3 版)》§4.1.1 指令地址码的个数:一条指令必须包含的四项信息、下条指令地址由 PC 隐含给出、四种地址码个数的含义(印刷页 p91~92)
- 同上 §4.2 指令系统设计:完备性、兼容性、均匀性、可扩充性四条原则(印刷页 p92)
- 同上 §4.2.4 操作类型:七类操作、调用指令与转移指令的区别、统一编址时可省去 I/O 指令(印刷页 p96~97)
- 同上 §4.2.7 指令系统设计风格:累加器型、栈型、通用寄存器型、Load/Store 型(印刷页 p99~100);图 4.5 MIPS 指令格式(印刷页 p104)
- 唐朔飞《计算机组成原理(第 3 版)》§7.1.2 指令字长:早期三种字长相等、指令字长可变时有单字长与多字长指令、多字长指令要多次访存才能取出一条完整指令、IBM 370 的指令字长为 16 位(半个字)/32 位(一个字)/48 位(一字半)与 Intel 8086 的六种指令字长、指令字长通常取 8 的整数倍、常用指令设计成短字长格式(印刷页 p304)
相关知识
指令格式与扩展操作码|数据寻址方式|指令执行过程|CISC 与 RISC