在指令系统设计中,如果我们希望在定长指令字结构(如固定16位)的前提下,同时支持多种地址数的指令(如三地址、二地址等),那就要采用一种精巧的策略 —— 扩展操作码(Expanded Opcode)。
扩展操作码是一种层次化的指令编码方式。通过可变长度操作码,根据前缀标记对指令分类,支持多样化的操作类型。
例如:
指令类型 | 地址数 | 地址位长 | 剩余操作码位 | 可分配操作数数量 |
---|---|---|---|---|
三地址 | 3 | 12 | 4 | 2⁴ = 16 条 |
二地址 | 2 | 8 | 4 | 2⁴ = 16 条(需扩展标记) |
一地址 | 1 | 4 | 8(含扩展) | 2⁶ = 64 条(留2条扩展) |
零地址 | 0 | 0 | 12(含扩展) | 2⁵ = 32 条 |
0000
~ 1110
1111
给二地址指令作为扩展前缀以设计:
15 条三地址 + 12 条二地址 + 62 条一地址 + 32 条零地址指令为目标,具体如下:
0000
~1110
(共15种)1111
作为扩展标记 ➜ 指向二地址指令1111
0000
~1011
(共12种)1100
~1111
(4种)指向下一层(一地址)1111 1100
~1111 1111
000000
~111101
(共62种)111110
、111111
(2种)用于零地址扩展1111 1111 11xx
(全部为1)0000
~1111
,即32种指令CPU **读取指令(16位)**后,按位判断指令类型:
识别条件 | 解析结果 |
---|---|
前4位 ≠ 1111 |
三地址指令 |
前4位 = 1111 且后4位 ≠ 1111 |
二地址指令 |
前8位 = 1111 1110 ~1111 1111 且后4位 ≠ 1111 |
一地址指令 |
前12位 = 1111 1111 1111 |
零地址指令 |
1111 0000 1010 1100
1111
➜ 二地址指令0000
➜ 二地址操作码 0
1111 1110 0000 1100
1111 1110
➜ 一地址指令1111 1111 1111 0010
1111 1111 1111
➜ 零地址指令HALT
, NOP
等如果上一层保留了 m 种扩展操作码,地址位为 n,则下一层最多表示指令数为:
指令数 = m × 2 n 指令数 = m \times 2^n 指令数=m×2n
举例说明:
特性 | x86(扩展操作码) | ARM(定长操作码) |
---|---|---|
架构类型 | CISC(复杂指令集) | RISC(精简指令集) |
操作码设计 | 多级前缀扩展 | 固定位宽操作码 |
指令长度 | 变长(1~15字节) | 定长(32位) |
硬件译码复杂度 | 高 | 低 |
典型应用 | PC、服务器 | 嵌入式设备、移动设备 |