指令字长 = 操作码长度 + 地址码总长度。
所有指令的操作码等长:n 位操作码 → 最多 $2^n$ 条指令。
根据指令使用频率分配操作码长度:
定长编码和可变长编码的折中方案:保留部分编码空间用于扩展,较短指令的操作码后面用特定模式表示「需要扩展」。
假设定长指令字 W 位、地址码每个 A 位、一条指令有 n 个地址码:
15/15/15 法:每级保留一个编码(如全 1)表示「继续扩展」,每级可编码的指令数 = $2^A - 1$。
8/64/512 法:第一级用 3 位(000–110)编码 7 条三地址指令,111 表示扩展;第二级用 6 位编码 64 条二地址指令……
定长指令字 16 位、每个地址码 4 位,设计 15 条三地址、15 条二地址、15 条一地址、16 条零地址指令:
三地址指令:OP(4) + A1(4) + A2(4) + A3(4) = 16 位 编码空间:0000~1110(15 种),保留 1111 用于扩展 二地址指令:1111 + OP(4) + A1(4) + A2(4) = 16 位 编码空间:1111_0000~1111_1110(15 种),保留 1111_1111 一地址指令:1111_1111 + OP(4) + A1(4) = 16 位 编码空间:1111_1111_0000~1111_1111_1110(15 种),保留全 1 零地址指令:1111_1111_1111 + OP(4) = 16 位 编码空间:16 种(16 条)
验证:$15 + 15 + 15 + 16 = 61$ 条指令 ✓;操作码总编码空间 $2^4 \times 4 = 2^6 = 64$ 种。
设计 14 条三地址、31 条二地址、15 条一地址、16 条零地址指令:
三地址:0000~1101(14 种),保留 1110、1111 两个扩展前缀 二地址:[1110/1111] + OP(4) + 2×4 位 2 个前缀 × 16 = 32 种,用 31 种,保留 1111_1111 扩展 一地址:1111_1111 + OP(4) + 1×4 位,取 15 种,保留全 1 零地址:1111_1111_1111 + OP(4),16 种
A 类 50%、B 类 30%、C 类 20%:
哈夫曼编码:A: 0(1位) B: 10(2位) C: 11(2位) 平均长度 = 0.5×1 + 0.3×2 + 0.2×2 = 1.5 位 等长编码:2 位 效率提升 = (2 − 1.5) / 2 = 25%
定长指令字 32 位、操作码 8 位、3 个地址码,每个地址码可指向 4GB 空间:
每个地址码位数 = ⌈log₂(4GB)⌉ = ⌈log₂(2^32)⌉ = 32 位 操作码(8) + 3×地址码(32) = 104 位 > 32 位!→ 放不下 改为一地址:8 + 32 = 40 位 > 32 位 → 也不行 改为寄存器型:OP(8) + R1(5) + R2(5) + R3(5) + 立即数(9) = 32 位 (假设 32 个寄存器,5 位编号)
设指令字长 W 位、地址码 A 位,n 地址指令最多编码 $2^{W-nA}$ 种。
$$n_0 \leq 2^{W} - n_1 \cdot 2^{A} - n_2 \cdot 2^{2A} - \cdots$$
(此为简化的约束公式,实际设计需要更精细的分析)
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。