计算机组成原理第 4 章:指令系统
408 计算机组成原理「指令系统」复习:核心知识点、真题题型、通用解法与易错点。
Last updated on
本章依据两套材料整理:408 真题 → 计算机组成原理 → 第 4 章 指令系统,以及408 模拟选择题 → 计算机组成原理 → 第 4 章 指令系统。网站真题页把本章划分为:指令格式、数据对齐与大/小端、指令寻址与数据寻址、CISC/RISC、高级语言与机器级代码对应。近年的综合题明显越来越喜欢把本章和数据表示、存储系统、操作系统页式存储、CPU 标志位一起考。(Any Docs)
内容按 408 高频题型与解法 组织,而不是机械按教材知识点展开。
一、先建立整章框架
这一章表面知识不多,但属于408计组里最容易出综合计算题的章节之一。
真正需要掌握的是下面 8 类问题:
| 题型 | 重要程度 | 核心能力 |
|---|---|---|
| 指令字段位数计算 | ★★★★ | OP、地址码、寄存器编号 |
| 扩展操作码 | ★★★★★ | 不同地址数指令共存 |
| 大小端与边界对齐 | ★★★★★ | 地址→字节内容 |
| 各种数据寻址方式 | ★★★★★ | EA 与操作数 |
| PC 相对寻址与转移 | ★★★★★ | “下一条指令地址 + 位移” |
| 机器码/汇编/C语言互译 | ★★★★★ | 看懂真实机器代码 |
| CALL、RET、栈 | ★★★ | 返回地址与 SP |
| RISC/CISC、ISA 概念 | ★★ | 选择题记忆 |
其中最值得重点投入时间的是:
扩展操作码 + 寻址方式 + 大小端 + 机器级程序。
二、题型一:指令格式与字段位数
1. 指令到底由什么组成?
最基本形式:
操作码告诉 CPU:
做什么。
例如:
- ADD
- SUB
- LOAD
- STORE
- JMP
地址码告诉 CPU:
对谁做。
2. 操作码至少需要多少位?
如果有 种不同操作,则操作码至少需要:
例如 48 条指令:
所以至少:
三、经典题型:扩展操作码
这是本章第一大重点。
真题 1:2017 年 408
题目
某计算机:
- 按字节编址;
- 指令字长固定;
- 只有三地址和二地址两种格式;
- 三地址指令 29 条;
- 二地址指令 107 条;
- 每个地址字段 6 位。
问:
指令字长至少多少位?
选项:
A. 24 位 B. 26 位 C. 28 位 D. 32 位
网站答案为 A。(Any Docs)
第一步:先看三地址指令
三个地址字段占:
29 条三地址指令至少需要:
位操作码。
因此理论指令长度:
位。
但是问题来了:
为什么答案不是 23?
因为机器按字节编址,指令需要按完整字节存放,因此至少:
第二步:确认剩余编码够不够扩展
5 位 OP:
种编码。
29 种给三地址指令,因此还剩:
种。
每一种剩余操作码都可以把一个 6 位地址字段“抢过来”继续当操作码。
于是可编码二地址指令:
而需要:
条,所以够用。
因此:
四、扩展操作码的本质
不要死背公式。
需要理解:
地址越少,腾出来给操作码的位越多,所以可以定义更多操作。
例如:
三地址:
OP | A1 | A2 | A3如果某个 OP 编码不用来表示三地址指令,就规定:
一旦看到这个 OP,后面的 A1 不再是地址,而是 OP 的继续部分。
于是变成:
OP扩展 | A2 | A3这样就是二地址指令。
继续扩展:
OP进一步扩展 | A3就是一地址指令。
最后所有地址字段都拿来扩展:
OP就是零地址指令。
五、真题 2:2022 年扩展操作码
题目
16 位定长指令:
- 地址码 6 位;
- 有零地址、一地址、二地址指令;
- 二地址指令 12 条;
- 一地址指令 254 条。
问:
零地址指令最多多少条?
答案:
(Any Docs)
第一步:二地址格式
两个地址字段:
所以基本操作码:
位。
共有:
种基本编码。
12 条给二地址指令,剩:
第二步:扩成一地址
每一个剩余编码再结合 6 位:
条一地址指令。
实际使用:
条。
所以还剩:
个一地址扩展编码。
第三步:再扩成零地址
再释放最后一个 6 位地址字段:
所以:
六、扩展操作码万能解法
遇到这种题,固定做四步:
第一步:从地址最多的格式开始
例如三地址。
先求基础 OP 位数。
第二步:算该级剩多少编码
第三步:少一个地址,就多出地址字段那么多位给 OP
若地址字段长度为 :
第四步:扣除下一类指令,再继续扩展
一直做到题目问的那一级。
七、模拟题中的高质量变式
网站模拟题有一道:
单地址指令 260 条,二地址指令 12 条,每个地址字段 6 位,求最短指令字长。
如果 OP 只有 4 位:
12 条二地址占掉 12 个,剩 4 个。
最多扩展:
条单地址指令。
但题目需要:
所以 4 位不够。
改为 5 位:
所以最短:
这道题非常适合检查是否真正理解扩展操作码,而不是只会套真题。(Any Docs)
八、题型二:ISA 到底规定什么?
2022 年真题
题目问哪些属于 ISA:
I. 指令字格式和指令类型 II. CPU 时钟周期 III. 通用寄存器数量和位数 IV. 加法器进位方式
答案:
(Any Docs)
怎么判断?
ISA 可以理解成:
软件和硬件之间公开的合同。
程序员、编译器能够“看见”的东西,通常属于 ISA。
例如:
- 有哪些机器指令;
- 指令格式;
- 寻址方式;
- 寄存器多少个;
- 寄存器多宽;
- 数据类型;
- 异常机制;
- 可见状态。
而:
- CPU 多少 GHz;
- ALU 内部怎么进位;
- 流水线几级;
- Cache 具体怎么做;
属于:
微体系结构实现。
九、题型三:大端、小端
这一部分和第 2 章数据表示经常一起考。
十、大小端到底是什么?
假设一个 32 位数据:
12 34 56 78H它包含四个字节:
12
34
56
78其中:
12是最高有效字节 MSB;78是最低有效字节 LSB。
大端 Big Endian
低地址放高有效字节:
地址 内容
1000 12
1001 34
1002 56
1003 78小端 Little Endian
低地址放低有效字节:
地址 内容
1000 78
1001 56
1002 34
1003 12十一、2016 年真题:直接读某个字节
题目
机器数:
1122334455667788H从地址:
00008040H开始存储。
采用小端。
问:
00008046H存什么?
(Any Docs)
小端从低地址开始:
8040 88
8041 77
8042 66
8043 55
8044 44
8045 33
8046 22
8047 11所以:
十二、2018 年真题:补码 + 小端 + 机器码
原机器代码:
C7 45 FC 00 00 00 00对应:
int i = 0;若改为:
int i = -64;问机器代码。
(Any Docs)
第一步:求 -64 的 32 位补码
因此:
第二步:小端排列
32 位立即数:
FF FF FF C0内存从低地址到高地址为:
C0 FF FF FF所以:
C7 45 FC C0 FF FF FF即:
十三、注意一个超级易错点
“数值的十六进制表示”和“内存中的字节顺序”不是一回事。
例如 CPU 中一个寄存器值:
6481FEFDH它还是:
6481FEFDH不会因为小端就变成:
FDFE8164H只有问:
它在内存中如何排列
才反过来。
网站模拟题正好有一题:
add r1,r2,-259
拼出的 32 位指令字为:
6481FEFDH但若问小端机器的内存中字节序列,就是:
FD FE 81 64(Any Docs)
这个区别必须牢牢记住。
十四、题型四:边界对齐
边界对齐和大小端经常捆绑。
基本原则
一般情况下:
char:1 字节边界;short:2 字节边界;int:4 字节边界;double:常见 8 字节边界。
假如 int 要按 4 字节对齐,那么它的首地址应满足:
short:
十五、2012 年经典真题
struct {
int a;
char b;
short c;
} record;
record.a = 273;首地址:
0xC008问:
0xC008内容;c的地址。
网站答案:
0x11
0xC00E(Any Docs)
1. 先分析 a
小端存储:
C008 11
C009 01
C00A 00
C00B 00所以:
2. b
char 占 1 字节:
C00C3. c
short 必须偶地址开始。
下一个地址:
C00D是奇数。
所以填一个 padding:
C00D:填充然后:
C00E:c因此:
十六、2020 年真题:边界对齐 + 小端
struct record {
short x1;
int x2;
} a;首地址:
2020FE00Hx2 机器数:
12340000H问 34H 所在地址。
(Any Docs)
布局:
FE00 x1
FE01 x1
FE02 padding
FE03 padding
FE04 x2
FE05 x2
FE06 x2
FE07 x212340000H 小端:
FE04 00
FE05 00
FE06 34
FE07 12所以:
十七、这种题的固定模板
看到:
struct + 地址 + 大小端
先不要碰数值。
先做:
第一步:布局
确定成员地址。
第二步:padding
确定边界对齐产生的空洞。
第三步:再处理字节序
最后才把具体数据拆成字节。
顺序不能反。
十八、题型五:数据寻址方式
这是本章最大核心。
建议把下面这张表背到看到题就能写。
| 寻址方式 | 有效地址/操作数 |
|---|---|
| 立即寻址 | 操作数 = A |
| 直接寻址 | |
| 间接寻址 | |
| 寄存器寻址 | 操作数 = |
| 寄存器间接 | |
| 基址寻址 | |
| 变址寻址 | |
| 相对寻址 | |
| 堆栈寻址 | 操作数在栈顶附近 |
十九、最重要的区别:EA 和操作数
这个坑每年都能坑人。
例如:
并不代表操作数是 3000H。
如果:
那么:
所以做寻址题必须分两步:
再:
二十、2013 年真题:变址寻址
题目给:
形式地址:
并给:
M[1000H]=2000H
M[2000H]=3000H
M[3000H]=4000H问变址寻址访问到的操作数。
(Any Docs)
变址:
因此:
真正操作数:
所以:
题目故意给:
M[1000]
M[2000]都是干扰信息。
二十一、直接寻址与间接寻址
假设形式地址:
且:
M[1000H]=2000H
M[2000H]=3000H直接寻址
操作数:
间接寻址
操作数:
所以间接寻址多一次访问存储器。
二十二、寄存器寻址与寄存器间接
若:
且:
寄存器寻址 R
操作数:
寄存器间接寻址 R
操作数:
网站模拟题恰好考了这个陷阱:立即寻址 600 和寄存器寻址 R 得到的操作数才是 600;直接寻址 600 和寄存器间接 R 得到的都是内存中的 700。(Any Docs)
二十三、基址与变址:最容易混
公式其实完全一样:
真正区别是:
谁变、谁不变,以及谁负责管理。
基址寻址
一般:
- 基址寄存器保存一段程序/数据所在区域的基地址;
- 形式地址给偏移;
- 基址往往由操作系统或装入程序确定;
- 便于重定位。
想象:
程序原来认为变量位于 offset=100操作系统把程序装入:
5000则:
变址寻址
一般:
- 形式地址给数组首地址;
- 变址寄存器保存下标或偏移;
- 变址寄存器不断变化。
所以最适合:
数组、循环。
2017 年真题
问:
最适合按照下标顺序访问一维数组的是?
答案:
(Any Docs)
二十四、2018 年真题:数组地址
double 数组:
A 首地址 = 2000H访问某个元素:
地址 = 2100Hdouble 占:
问下标。
(Any Docs)
偏移:
而:
字节。
所以:
答案:
二十五、数组地址必须会的万能公式
一维数组:
例如 int:
于是编译器经常把:
a[i]翻译成:
slli temp, i, 2
add temp, base, temp
lw x, 0(temp)因为:
二十六、二维数组是近年重点
C语言二维数组:
int a[M][N];按行优先存储。
于是:
如果每行 64 个 int:
所以:
这正是 2023 年真题的核心。(Any Docs)
二十七、题型六:相对寻址
这是必须满分掌握的东西。
核心公式不是:
而通常是:
二十八、2009 年真题
转移指令:
- 首地址 2000H;
- 长 2 字节;
- 位移 06H;
- 每取一个字节 PC 加 1。
(Any Docs)
取完后:
再加:
所以:
答案:
二十九、为什么一定是“下一条指令”?
因为 CPU 先取当前指令。
取指结束以后:
PC 通常已经自动指向下一条顺序指令。
然后执行阶段才计算:
因此 PC 的基准不是当前指令起始地址。
这是相对寻址最大的坑。
三十、反向跳转:模拟题
题目:
- 两字节跳转指令;
- 执行前 PC=200CH;
- 目标为 1FB0H;
- 第二字节为 8 位补码偏移。
(Any Docs)
取完指令:
偏移:
8 位补码:
因此:
三十一、相对寻址万能模板
以后看到:
JMP / Jcc / CALL + 相对位移
直接写:
然后:
如果题目反过来求 offset:
三十二、带补码位移必须符号扩展
例如 16 位形式地址:
FF12H如果它表示补码,则不是:
而是一个负数。
扩展到 32 位:
FFFFFF12H三十三、2019 年真题:基址 + 补码 + 大端
题目:
- 基址寄存器:
F0000000H- 位移:
FF12H16 位补码;
- 操作数:
1234FF00H- 大端;
- 问最低有效字节 LSB 地址。
(Any Docs)
第一步:符号扩展
第二步:EA
得到:
第三步:判断 LSB 在哪里
32 位共 4 字节。
大端:
EA 12
EA+1 34
EA+2 FF
EA+3 00所以 LSB 位于:
即:
这道题把:
基址 + 补码符号扩展 + 大端
三个知识点一次考完,非常典型。
三十四、题型七:寻址范围
2014 年真题
32 位指令:
- 操作码+寻址方式:8 位;
- 16 个通用寄存器;
- Store 有源寄存器、基址寄存器;
- 其余位为补码偏移。
(Any Docs)
16 个寄存器需要:
位编号。
两个寄存器字段:
所以偏移量:
位。
16 位补码范围:
即:
三十五、题型八:直接、先变址后间址等复合寻址
2016 年真题
若:
先变址,后间址
形式地址 D,变址寄存器 I。
(Any Docs)
先变址:
然后间址:
因此:
所谓“先 X 后 Y”:
就按文字顺序一层一层算。
三十六、非常重要:指令寻址 vs 数据寻址
很多人把两个概念混在一起。
指令寻址
回答:
下一条执行哪条指令?
包括:
- 顺序寻址;
- 跳跃寻址。
数据寻址
回答:
当前指令需要的数据在哪里?
包括:
- 立即;
- 直接;
- 间接;
- 寄存器;
- 基址;
- 变址;
- 相对……
网站模拟题也专门考过:程序运行中通常是指令寻址、数据寻址反复交替进行。(Any Docs)
三十七、题型九:2010 年综合大题——本章极经典
这是非常值得完整掌握的一道题。
题目给出 16 位指令格式
15~12 | 11~9 | 8~6 | 5~3 | 2~0
OP | Ms | Rs | Md | Rd其中:
- OP:操作码;
- Ms:源寻址方式;
- Rs:源寄存器;
- Md:目的寻址方式;
- Rd:目的寄存器。
主存:
- 128KB;
- 字长 16 位;
- 按字编址。
并要求:
- 最多多少指令、寄存器?
- MAR/MDR 至少几位?
- 编码
add (R4),(R5)+; - 执行后谁变化?
(Any Docs)
第一问:指令数
OP 4 位:
最多:
通用寄存器
寄存器编号 3 位:
所以:
个。
MAR
主存容量:
字长:
按字编址,所以字数:
而:
因此:
MDR
一个存储字:
所以:
三十八、2010 真题的机器码编码
给:
add (R4),(R5)+且:
- ADD:
0010 (Rn):寄存器间接 →001(Rn)+:寄存器间接自增 →010- R4:
100 - R5:
101
所以:
0010 001 100 010 101分组:
0010 0011 0001 0101得到:
(Any Docs)
三十九、执行后的数据变化
已知:
R4 = 1234H
R5 = 5678H
M[1234H] = 5678H
M[5678H] = 1234H源:
(R4)所以源操作数:
目的:
(R5)+原目的操作数:
ADD:
写回:
同时 (R5)+ 自动自增。
因为按字编址:
于是:
最终:
四十、这里有一个很重要的变式
如果题目改成:
按字节编址
且访问的是 16 位字。
那么自增量通常就可能是:
而不是 1。
所以永远判断:
地址的最小单位是什么?
四十一、题型十:条件转移与标志位
机器级代码题离不开:
- CF;
- ZF;
- SF/NF;
- OF。
ZF
结果为 0:
SF / NF
通常保存结果最高位。
结果负:
CF
主要用于:
无符号数加减。
减法时:
发生借位 → CF=1。
OF
主要判断:
有符号数运算是否溢出。
四十二、无符号和有符号比较必须分开
这是408常考陷阱。
无符号小于
做:
如果发生借位:
所以:
通常对应 CF。
无符号小于等于
对应:
或:
即:
2013 年真题就要求设计这样的条件检测位。(Any Docs)
四十三、有符号“小于”
不能简单看 SF。
正确关系:
网站模拟题专门考了 jl:
有符号小于时转移。
答案正是:
(Any Docs)
四十四、有符号条件判断建议记这组
严格小于:
大于等于:
小于等于:
大于:
四十五、题型十一:CALL / RET / 栈
网站模拟题:
题目
双字长 CALL:
- 当前 PC=2000H;
- 目标地址 4000H;
- SP=0100H;
- 按字编址;
- 栈向低地址增长;
- 先修改 SP,再压数据。
问 CALL 后:
SP 和新栈顶是什么?
答案:
00FFH
2002H(Any Docs)
为什么不是把 4000H 压栈?
CALL 做:
- 保存返回地址;
- PC 跳到函数入口。
返回地址不是被调函数地址。
而是:
CALL 执行完以后下一条顺序指令地址。
双字长、按字编址:
所以压入:
SP
栈向低地址增长:
然后:
最后:
四十六、CALL 万能模型
CALL 的核心可以概括成:
然后:
RET 则:
四十七、题型十二:高级语言与机器级代码
这是近几年本章最值得重视的部分。
真题页可以明显看到:
- 2017;
- 2019;
- 2023;
- 2024;
连续出现了 C / 汇编 / 机器码相关综合题。(Any Docs)
不能只背:
“立即寻址是什么”。
必须真的会看:
mov
add
sub
cmp
jmp
call
ret
slli
lw四十八、2017 真题:判断 RISC/CISC
机器代码中出现:
push ebp
cmp dword ptr [ebp-0Ch], ecx
shl edx,1不同指令长度不同。
例如:
push:1 字节;cmp:3 字节;shl:2 字节。
因此属于:
(Any Docs)
为什么?
因为典型 x86/CISC 特点:
- 指令长度可变;
- 指令格式较多;
- 可直接对内存操作;
- 指令功能复杂。
四十九、机器代码长度怎么算?
2017 真题给:
第一条:
00401020最后一条 ret:
0040107F且 ret 占 1 字节。
因此结束位置的下一地址:
00401080总字节数:
得到:
字节。
所以:
(Any Docs)
五十、这种问题千万不要用
直接作为大小。
如果最后一条指令长度是 ,则:
五十一、2017 真题:unsigned 陷阱
程序里:
unsigned n当:
计算:
不是 -1。
而是 32 位无符号整数模:
运算。
所以:
比较:
和:
显然无符号:
减法发生借位,所以:
(Any Docs)
五十二、2017 真题另一个非常好的问题
源码里整数:
power *= 2;编译成:
shl edx,1如果把 int 换成 float,还能这样吗?
不能。
整数左移:
通常等价于:
但浮点数编码包含:
符号位 | 阶码 | 尾数整体二进制左移会破坏字段意义。
所以浮点乘 2 应使用:
浮点运算指令。
(Any Docs)
五十三、2019 真题:递归 + CALL + 相对寻址
这道题非常有代表性。
代码实现:
有:
cmp
jle
call
imul
jmp
ret其中:
00401025 E8 D6 FF FF FF call f1(Any Docs)
CALL 下一条指令地址
CALL 从:
00401025开始,长 5 字节。
因此:
CALL 的相对偏移
目标:
00401000所以:
即:
32 位补码:
FFFFFFD6H为什么机器码里是:
D6 FF FF FF而不是:
FF FF FF D6因为小端。
于是:
这是“相对寻址 + 补码 + 小端”三合一。(Any Docs)
五十四、2019:整数溢出
但 32 位 int 最大正数:
显然:
所以溢出。
正确修改方向:
返回值和乘法中间结果都扩大到 64 位。
例如:
long long网站真题解析也是这个结论。(Any Docs)
五十五、乘法溢出的高低位判据
如果两个 32 位补码相乘得到 64 位结果:
高32位 H | 低32位 L如果结果能够正确压缩成 32 位,则:
高 32 位必须恰好等于低 32 位符号位的扩展。
即如果 L 的最高位是 0:
如果 L 的最高位是 1:
否则:
这也是 2019 真题的考点。(Any Docs)
五十六、2023 年真题:机器级代码综合题
这题很重要,因为代表当前408命题方向。
C代码:
for (i=0;i<24;i++)
for (j=0;j<64;j++)
a[i][j]=10;其中第19条机器指令:
004010AE
C7 84 82 00 20 42 00 0A 00 00 00
mov [ecx+edx*4+00422000h],0Ah(Any Docs)
考法1:求下一条指令地址
数机器码字节:
C7
84
82
00
20
42
00
0A
00
00
00共:
所以:
答案:
五十七、考法2:判断 JMP 寻址
有:
00401079 EB 09 jmp 00401084本条长 2 字节。
下一条地址:
再加位移:
所以:
(Any Docs)
五十八、考法3:二维数组地址
指令:
mov [ecx+edx*4+00422000h],0Ah数组:
int a[24][64]首地址:
00422000H已知:
edx = j那么:
因此 ecx 必须保存:
即:
(Any Docs)
五十九、考法4:立即寻址
指令:
mov [...],0Ah常数:
0Ah直接写在机器指令中。
因此源操作数是:
六十、考法5:根据机器码判断大小端
机器指令里数组首地址:
00422000H在内存中对应:
00 20 42 00常数:
0000000AH对应:
0A 00 00 00所以:
低有效字节放在低地址。
即:
(Any Docs)
六十一、2023 题为什么特别值得学?
因为这一题把:
- 指令长度;
- PC;
- 相对寻址;
- 立即寻址;
- 二维数组;
- 小端;
- 页式存储;
全部串起来了。
这就是现在408越来越典型的模式:
一道综合题跨三四章。
六十二、2024 年真题:RISC-V 风格机器级代码
源码:
sum += a[i];对应:
slli r4,r2,2
add r4,r3,r4
lw r5,0(r4)
add r1,r1,r5(Any Docs)
逐条解释。
第一条
slli r4,r2,2即:
也就是:
所以 R2 保存:
第二条
add r4,r3,r4即:
因此 R3 保存:
第三条
lw r5,0(r4)取得:
第四条
add r1,r1,r5即:
所以:
最终映射:
r1 → sum
r2 → i
r3 → a首地址(Any Docs)
六十三、2024 年:真正算数组元素
题目给:
数组首地址:
0013DFF0Hint:
所以:
得到:
内存:
0013E004 : DC
0013E005 : EC
0013E006 : FF
0013E007 : FF小端恢复成数:
FF FF EC DC所以:
(Any Docs)
六十四、继续算 sum
原:
sum = 00001332H所以:
32 位运算结果:
这类题说明必须把:
补码加法 + 大小端 + 数组寻址
真正联通起来。
六十五、2024:数组类型改变怎么办?
原来:
int a[]每个元素:
字节,因此:
slli r4,r2,2如果改成:
short a[]每个:
字节。
因此变成:
slli r4,r2,1(Any Docs)
六十六、以后看到移位计算数组偏移量,直接这样判断
若元素大小:
则:
所以:
| 类型大小 | 常见偏移 |
|---|---|
| 1 B | 不移 |
| 2 B | 左移 1 |
| 4 B | 左移 2 |
| 8 B | 左移 3 |
六十七、题型十三:CISC 与 RISC
真题直接考过。
2009 年真题:
关于 RISC,错误的是“普遍采用微程序控制器”。
答案为该项。(Any Docs)
六十八、RISC 特征
可以直接记成:
少、简、规、寄、流水、硬布线。
即:
- 指令种类较少;
- 寻址方式较少;
- 指令格式规整;
- 大量通用寄存器;
- 适合流水线;
- 多使用硬布线控制;
- Load/Store 思想明显;
- 编译器承担更多优化工作。
六十九、CISC 特征
相对来说:
- 指令多;
- 寻址方式多;
- 指令长度可能变化;
- 指令功能复杂;
- 一条指令可能完成复杂操作;
- 传统实现较常使用微程序控制。
但千万不要把它理解成:
CISC 不能流水线。
这是错的。
网站模拟题也专门指出:CISC 同样可以使用流水线,只是实现通常更复杂。(Any Docs)
七十、RISC / CISC 高频判断陷阱
错误说法 1
RISC 普遍微程序控制。
错。
典型 RISC 更倾向:
错误说法 2
CISC 不支持流水线。
错。
错误说法 3
RISC 指令一定只有一个周期。
教材表述通常是:
大多数指令执行时间规整、易于单周期或流水化。
不要把所有架构现实实现绝对化。
错误说法 4
RISC 寄存器少。
恰好相反:
七十一、关于本站模拟题里一个分类问题
模拟题第 4 章开头还收录了诸如:
微指令字段直接编码、水平型/垂直型微指令、控制存储器容量
这样的题。(Any Docs)
这些题本身是好题,但是从408标准知识结构看,它们更属于下一章:
CPU / 控制器 / 微程序控制器
而不是本章“机器指令系统”的核心。
因此复习第 4 章时,不要因为它们位于网页第 4 章就把微程序控制当成第 4 章核心重点。等学第 5 章 CPU 时再系统解决更合适。
七十二、本章所有寻址方式必须形成这张脑图
可以直接这样记。
操作数就在指令里
操作数就在寄存器里
指令里的 A 就是内存地址
指令里的 A 指向一个“地址”
寄存器存的是内存地址
基地址 + 偏移
数组首址 + 下标
下一条指令地址 + 位移
七十三、寻址题统一解题法
无论题目怎么变,做四步。
Step 1:确认寻址方式
不要急着算。
Step 2:写公式
例如变址:
相对:
寄存器间接:
Step 3:判断 A 是否为补码
如果是补码:
先符号扩展。
Step 4:最后区分 EA 和操作数
如果 EA 指向内存:
七十四、机器级代码题统一解题法
现在408越来越爱考这种,建议固定按下面顺序:
1. 看地址
先知道每条机器指令从哪开始。
2. 数机器码字节
得到指令长度。
3. 看汇编语义
确定寄存器谁代表谁。
4. 看寻址表达式
例如:
[base + index*scale + displacement]转换为:
5. 看立即数
立即数直接就是操作数。
6. 判断大小端
把连续字节重新组合。
7. 遇到 JMP/CALL
永远先算:
再算位移。
8. 遇到 C 数据类型
先看:
- signed / unsigned;
- char / short / int;
- 数组元素大小。
七十五、最值得背的 12 个公式/结论
1. 操作码位数
2. 寄存器编号
若有 个寄存器:
3. 补码范围
位:
4. 直接寻址
5. 间接寻址
6. 寄存器间接
7. 基址
8. 变址
9. 相对寻址
这里的 PC 通常是:
已经指向下一条指令的 PC。
10. 一维数组
11. 二维数组
C语言:
其中 N 为每行元素数。
12. 有符号小于
七十六、本章最容易丢分的 10 个坑
坑 1:相对寻址拿当前指令首地址加 offset
错。
通常是:
坑 2:看到 FFxx 就当正数
先看题目说没说:
补码表示。
如果说了,需要符号扩展。
坑 3:EA 与 Operand 混淆
通常:
坑 4:把寄存器间接当寄存器寻址
寄存器寻址:
寄存器间接:
坑 5:基址与变址死看公式
公式一样。
看用途:
基址 → 重定位。
变址 → 数组。
坑 6:把寄存器里的数按小端倒过来
不行。
大小端只涉及:
多字节数据在按字节编址内存中的排列。
坑 7:struct 忘记 padding
先排结构体地址,再处理大小端。
坑 8:CALL 把目标地址压栈
CALL 压入的是:
坑 9:signed / unsigned 条件码混用
无符号主要看:
有符号主要看:
坑 10:机器码地址差少算最后一条长度
必须算到:
最后一条指令之后的地址。
七十七、结合真题,怎样判断本章重点?
从网站所收录真题可以看出:
第一梯队:★★★★★
寻址方式
典型年份包括 2009、2011、2013、2014、2016、2017、2018、2019、2020,以及 2010/2013 大题。(Any Docs)
这几乎可以视为:
本章绝对核心。
第一梯队:★★★★★
机器级代码 + C语言
2017、2019、2023、2024 都有很有代表性的综合考查。(Any Docs)
而且近年的综合程度明显高于单纯背概念。
第二梯队:★★★★
大小端 + 数据存放 + 对齐
2012、2016、2018、2020,以及 2019、2023、2024 综合题都涉及或可关联。(Any Docs)
第二梯队:★★★★
指令格式 + 扩展操作码
2017、2022 都有直接真题,2021 综合题还要求分析 R/I/J 型格式。(Any Docs)
第三梯队:★★
RISC/CISC
本身不难,通常作为选择题或机器代码综合题中的一个小问。
七十八、2021 年综合题值得额外理解
网站的 2021 真题给了一种 16 位 ISA:
- R 型;
- I 型;
- J 型;
- 2 位寄存器号;
- I 型有 6 位立即数;
- J 型有 10 位 target。
并问:
- ALU 宽度;
- 主存空间;
- IR/MAR/MDR;
- 能定义多少操作;
- 寄存器数;
- 减法/乘法结果及溢出;
- imm 符号扩展;
- 无条件转移格式。
(Any Docs)
这类题的意义在于:
不要把“指令格式题”理解成只有扩展操作码。
它还可能要求从一个 ISA 反推整个机器结构。
例如字长 16 位:
地址线 20 位、按字节编址:
16 位定长指令:
20 位地址:
8 位数据总线:
寄存器编号 2 位:
个寄存器。
七十九、预测未来很可能出现的考法
基于这些真题,建议特别防下面几种组合。
预测 1:RISC-V 机器码 + 数组 + Cache
给:
slli
add
lw要求计算:
- 数组元素地址;
- 所属 Cache 块;
- Cache 组号;
- 是否命中;
- 最终寄存器值。
这是:
第 3 章 + 第 4 章。
2024 已经非常接近这个方向。
预测 2:机器码 + 虚拟地址 + TLB/页表
例如给:
lw r5,12(r4)要求:
- 算有效地址;
- 求虚拟页号;
- 查 TLB;
- 查页表;
- 得物理地址;
- 再查 Cache。
这是极其自然的:
指令系统 + 存储层次 + 操作系统
综合题。
2023/2024 的命题已经表现出这种跨章节趋势。(Any Docs)
八十、预测 3:分支指令 + 标志位 + 流水线
给:
cmp
jge问:
- 标志位;
- 是否跳转;
- 目标地址;
- 流水线是否冲刷;
- CPI 或周期数。
这会把:
第 2 章运算 + 第 4 章指令 + 第 5 章流水线
串起来。
八十一、预测 4:struct + 对齐 + Cache
给:
struct {
char a;
int b;
short c;
} x[100];再给 Cache:
- 块大小;
- 组数;
- 映射方式。
问访问:
x[i].b的地址和 Cache 位置。
必须先:
- 求结构体内部 padding;
- 求
sizeof(struct); - 求数组元素地址;
- 再求 Cache 地址字段。
这类综合题质量很高。
八十二、预测 5:扩展操作码反推设计
不直接问:
最多多少条零地址指令。
而是问:
要同时支持 X 条三地址、Y 条二地址和 Z 条一地址,至少多长指令?
这种题本质仍是:
所以只要真正理解扩展操作码,不怕任何变形。
八十三、给出一道很值得练的自拟综合题
某 32 位小端计算机按字节编址,执行:
lw r3,-8(r2)已知:
r2 = 00002004H内存:
00001FFC 78
00001FFD 56
00001FFE 34
00001FFF 12问:
- 属于什么寻址方式?
- EA 是多少?
- r3 最终是多少?
第一步:寻址方式
形式:
-8(r2)属于基址/基址加偏移形式。
第二步:EA
第三步:恢复32位数
低地址依次:
78 56 34 12小端恢复:
12345678H因此:
这一道题就同时训练了:
- 补码偏移;
- 基址寻址;
- 有效地址;
- 小端。
八十四、再来一道相对寻址预测题
某转移指令:
首地址 = 1000H
长度 = 4B
16位相对位移字段 = FFF8H问跳转目标。
位移:
FFF8H是 16 位补码:
下一条地址:
因此:
所以:
这里最大陷阱就是有人算:
得到错误答案。
八十五、这一章复习到什么程度才算真正学会?
至少要做到下面这些不需要翻书。
看到:
29条三地址、107条二地址、地址字段6位马上想到:
扩展操作码。
看到:
FF12H,补码位移马上想到:
符号扩展。
看到:
jmp
call
jge马上想到:
看到:
[r3+r2*4]马上想到:
数组首地址 + 下标 × 元素大小。
看到:
DC EC FF FF且小端,马上恢复:
FFFFECDCH看到:
jl马上想到:
看到:
char + int + short马上先算:
alignment / padding。
看到:
CALL马上想到:
返回地址入栈,而不是目标地址入栈。
如果这些已经形成条件反射,第 4 章基本就稳了。
八十六、最后给出一份本章复习优先级
如果现在准备408强化,建议按这个顺序刷:
- 所有寻址方式及 EA 计算
- PC 相对寻址
- 数组地址计算
- 小端/大端
- 边界对齐
- 机器级代码与 C 语言对应
- 扩展操作码
- CALL / RET / 标志位
- ISA
- RISC / CISC
尤其推荐把网站中的这些题真正自己再算一遍:
2010 综合题 → 2013 条件转移大题 → 2017 指令格式与机器级代码 → 2019 递归机器级代码 → 2021 ISA 格式综合题 → 2023 二维数组机器级代码 → 2024
sum += a[i]综合题。
这几道基本把本章从传统“寻址方式”一直覆盖到现在408喜欢考的“C语言—汇编—机器指令—存储系统”综合方向。(Any Docs)
网站本身也明确建议分析408时遵循“知识点 → 真题 → 总结命题方式 → 模拟题补充”的路径;本章同样按这个顺序筛题,而没有把模拟题数量直接当成考频。(Any Docs)