首页/计算机组成原理/指令系统/指令格式 🔗 在 Obsidian 中打开
计算机组成原理 · 指令系统

指令格式

重要度 ⭐⭐⭐⭐⭐指令系统操作码地址码定长变长指令字长
速查
指令 = 操作码 + 地址码。按地址码数目分:三地址(A1 ← A2 OP A3)、二地址(A1 ← A1 OP A2)、一地址(隐含 ACC)、零地址(栈式)。操作码位数 n → 最多 $2^n$ 条指令;RISC 用定长、CISC 用变长。

概述

指令是 CPU 执行操作的最小单位。指令格式定义了指令的二进制编码方式,包括操作码和地址码两大部分。指令格式直接影响 CPU 的设计复杂度和程序的执行效率。

指令的基本组成

| 操作码 OP | 地址码 A1 | 地址码 A2 | ... | 地址码 An |

操作码(Operation Code)

  • 指定操作类型(加、减、与、或、跳转等)
  • n 位操作码可表示 $2^n$ 种操作

地址码(Address Code)

  • 指定操作数的来源和结果的去向
  • 可以是寄存器号、内存地址、I/O 端口号

按地址码数目分类

三地址指令

OP A1 A2 A3
含义:A1 ← (A2) OP (A3)
例:ADD R1, R2, R3  → R1 ← R2 + R3
  • 优点:表达能力强
  • 缺点:指令字长较长

二地址指令

OP A1 A2
含义:A1 ← (A1) OP (A2)
例:ADD R1, R2  → R1 ← R1 + R2
  • 最常用的指令格式
  • A1 既是源操作数又是目的操作数

一地址指令

OP A1
含义(单操作数):A1 ← OP(A1)
例:INC R1  → R1 ← R1 + 1
例:NOT R1  → R1 ← ~R1

含义(隐含操作数):ACC ← (ACC) OP (A1)
例:ADD [1000]  → ACC ← ACC + M[1000]

零地址指令

OP
含义:无操作数或隐含操作数
例:NOP(空操作)
例:RET(返回,隐含从栈取返回地址)
例:PUSH/POP(隐含栈指针操作)
地址码数目与性能的关系地址码越多 → 表达能力越强 → 指令字长越长;地址码越少 → 指令越短 → 需要更多指令完成同一任务。

操作码设计

定长操作码

所有指令的操作码长度相同
例:8 位操作码 → 最多 256 条指令
  • 优点:译码简单、快速
  • 缺点:操作码空间利用率低
  • 适用:RISC 架构(如 MIPS、ARM)

变长操作码(扩展操作码)

操作码长度可变,通过前缀区分
例:
0000 xxxx xxxx xxxx → 4 条指令(0 地址)
001  xxx xxx xxxx xxxx → 16 条指令(1 地址)
01   xxx xxx xxx xxx xxxx → ...(2 地址)
10   ... → ...(3 地址)

扩展操作码设计原则

  1. 短操作码分配给常用指令
  2. 长操作码分配给不常用指令
  3. 高位做前缀,区分不同地址码数量

扩展操作码例题

指令字长 16 位,每地址 4 位:
三地址:3×4 = 12 位地址码,操作码 4 位 → 2^4 = 16 条
  取 4 条 → 操作码 0000~0011
二地址:2×4 = 8 位地址码,操作码 8 位
  从三地址操作码扩展:0000xxxx → 16 个编码
  取 12 条 → 操作码 00000000~00001011
一地址:1×4 = 4 位地址码,操作码 12 位
  从二地址操作码扩展:00000000xxxx → 16 个编码
  取 64 条 → 需要 4 个二地址前缀 × 16 = 64
零地址:无地址码,操作码 16 位
  从一地址操作码扩展:000000000000xxxx → 16 个编码
  取 128 条 → 需要 8 个一地址前缀 × 16 = 128
考点扩展操作码要求短操作码不能是长操作码的前缀,否则译码产生歧义——这是设计时最易错的地方。

指令字长

固定长度指令

  • 所有指令长度相同
  • 优点:取指简单、对齐访问
  • 缺点:空间浪费
  • 适用:RISC(如 MIPS 32 位固定)

可变长度指令

  • 指令长度可变(1 字节到多字节)
  • 优点:空间效率高
  • 缺点:取指复杂
  • 适用:CISC(如 x86,1~15 字节)
易混指令字长可以 $\neq$ 机器字长;指令字长通常是字节的整数倍(半字长、单字长、双字长指令)。

操作码优化技巧

哈夫曼编码

  • 根据指令使用频率编码
  • 常用指令用短编码,不常用指令用长编码
  • 平均指令长度最短

定长 + 变长混合

  • 操作码部分定长
  • 地址码部分变长
  • 兼顾译码速度和空间效率

指令格式设计考虑因素

  1. 指令集大小:影响操作码位数
  2. 寄存器数量:影响地址码位数
  3. 寻址方式:需要寻址方式位
  4. 数据类型:影响操作码编码
  5. 指令字长约束:通常是字节的整数倍

x86 指令格式(实例)

| 前缀(0-4B) | 操作码(1-3B) | ModR/M(0-1B) | SIB(0-1B) | 偏移(0-4B) | 立即数(0-4B) |
  • 变长指令:1~15 字节
  • ModR/M 指定寻址方式
  • SIB 指定比例变址

MIPS 指令格式(实例)

R 型

| opcode(6) | rs(5) | rt(5) | rd(5) | shamt(5) | funct(6) |

I 型

| opcode(6) | rs(5) | rt(5) | immediate(16) |

J 型

| opcode(6) | address(26) |
观察MIPS 全部 32 位定长,操作码固定 6 位 → 定长操作码 + 定长指令,流水线友好。

易错点

必记
  1. 扩展操作码中,短操作码不能是长操作码的前缀(否则歧义)。
  2. 指令字长 $\neq$ 机器字长(可能不同)。
  3. 地址码数目越多,指令功能越强但字长越长。
  4. 变长指令的取指比定长复杂得多。
  5. 操作码位数决定了最大指令数($2^n$)。
  6. RISC 用定长操作码,CISC 用变长操作码。
  7. 一地址指令可能是单操作数或隐含操作数(ACC)。

交互动画 · 指令格式位域

16 位指令字 · 每格 4 位 · 橙色 = 操作码 · 绿色 = 地址码 三地址指令 A1 ← A2 OP A3
切换指令格式,查看操作码与地址码的位域划分
点击上方按钮开始
示意图:一行 16 位;橙色块为操作码,绿色块为地址码。可对比「地址码越少 → 留给操作码的位数越多」的扩展趋势。

相关知识点

addressing-modes cisc-and-risc instruction-length-and-opcode

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。