第 4 章 名词库
这一页是复习主入口。 目标是把第 4 章的名词收全,并把每个词的边界和适用范围钉死。
每条最多四行:是(定义)/不是(划掉最常见的误解)/易混(成对的对手)/范围(该结论在什么条件下才成立)。
建设进度:✅ 4.1 指令系统 ✅ 4.2 指令的寻址方式 ✅ 4.3 程序的机器级代码表示 ✅ 4.4 CISC和RISC的基本概念 (全章完整)
4.1.1 指令集体系结构
指令集体系结构 ISA
- 是:软件与硬件之间机器语言级的正式契约,规定指令格式、类型、寻址方式、数据类型、寄存器组织、存储模型、I/O 方式、异常中断机制、特权级。
- 不是:不是一个部件,主板上找不到它;也不是”越底层越 ISA”。
- 易混:↔ 微体系结构(在它下面);↔ ABI(在它上面)。
- 范围:判据是「改了之后老程序还能不能跑」。
微体系结构 Microarchitecture
- 是:同一份 ISA 的一种硬件实现——流水线深度、Cache 参数、控制器实现方式、分支预测、乱序执行。
- 不是:不属于 ISA。改了它,老程序照跑,只是快慢不同。
- 范围:主频、制程、超标量、乱序全部在这一层。
ABI 应用程序二进制接口
- 是:同一 ISA 上二进制模块的互操作约定——调用约定、栈帧布局、目标文件格式、系统调用编号。
- 不是:不属于 ISA。改了它,机器码依然合法,但模块之间接不上。
- 易混:↔ ISA。同一颗 x86 上 Windows 与 Linux 的 ABI 不同,指令编码完全相同。
汇编语法(Intel / AT&T)
- 是:助记符的书写规则,由汇编器约定。
- 不是:不属于 ISA。两种语法汇编出的机器码一个字节不差。
预处理
- 是:
.c→.i,宏展开、插入头文件、条件编译,纯文本替换。 - 范围:完全不涉及 ISA,输出仍是 C 代码。
编译
- 是:
.i→.s,生成目标机器的汇编代码。 - 范围:ISA 的主要客户,换 ISA 要换编译器后端。
汇编(过程)
- 是:
.s→.o,按 ISA 编码表逐条译成二进制。 - 范围:跨模块引用的地址先填 0,同时留下重定位记录。
链接
- 是:符号解析(把引用接到定义)+ 重定位(按最终布局补齐地址)。
- 不是:链接器基本不看指令语义,只认符号表和重定位类型。
可重定位目标文件 .o
- 是:已经是机器码,但地址尚未最终确定的目标文件。
- 易混:↔ 可执行文件(地址已确定)。
特权指令
- 是:只能在内核态执行的指令(如设置页表基址、开关中断)。
- 范围:机制属于 ISA,“哪些操作需要特权”由 ISA 与 OS 共同划定。
4.1.2 指令的基本格式
操作码 OP
- 是:指令中说明”做什么”的字段。
- 范围:定长时位于最高
位且位置固定;扩展操作码时长度可变但仍从最高位开始。
地址码 A(形式地址)
- 是:指令中说明”对谁做”的字段。
- 不是:里面装的不一定是主存地址——也可以是寄存器号、立即数、位移量、端口号。
- 范围:它代表什么,由操作码和寻址方式共同决定。
机器字长
- 是:CPU 一次能处理的二进制位数 = 通用寄存器位数 = ALU 宽度。
- 易混:↔ 存储字长、指令字长。三者互相独立。
存储字长
- 是:一个存储单元的位数,等于 MDR 的位数。
- 范围:见 3.2.3。
指令字长
- 是:一条指令的总位数。
- 范围:
存储字长( 可为 );取指访存次数 指令字长 存储字长。
单字长 / 双字长 / 半字长指令
- 是:指令字长为存储字长的 1 倍 / 2 倍 / 一半。
- 不是:不是相对机器字长说的。
四地址指令
- 是:
OP A1 A2 A3 A4,给出下条指令地址。 - 范围:纯理论格式,现实不存在。PC 的发明就是把它省掉。
三地址指令
- 是:
,下条地址由 PC 隐含。 - 范围:直接寻址、单字长时共访存 4 次。
二地址指令
- 是:
。 - 不是:
的原值不保留,被结果覆盖。 - 范围:共访存 4 次。
一地址指令
- 是:
(双操作数型),或 (单操作数读改写型)。 - 范围:双操作数型访存 2 次,读改写型 3 次。
零地址指令
- 是:
NOP、HLT,或堆栈机的运算指令。 - 不是:不一定不访存——堆栈机取操作数要访存(软堆栈)。
累加器 ACC
- 是:一地址指令中隐含的操作数来源兼结果去向。
定长指令字
- 是:所有指令长度相同。
- 易混:↔ 定长操作码。两个维度独立,可自由组合。
- 范围:PC 增量恒定、取指与译码可并行 → 流水线友好。
变长指令字
- 是:指令按需长短不同(x86:1~15 字节)。
- 范围:代码密度高,代价是取指与译码的串行依赖。
4.1.3 定长操作码指令格式
定长操作码
- 是:所有指令的操作码位数相同、位置相同(最高
位)。 - 范围:
位最多 条指令; 条指令至少 位。“最多”和”至少”是两个问题。
编码容量
- 是:一组操作码位数能区分的指令条数上限。
- 范围:
只在定长操作码下成立;扩展操作码下这个上界不适用。
地址字段位数
- 是:
, 为指令字长、 为操作码位数、 为等长地址字段个数。 - 范围:
位 → 最多 个通用寄存器,或 个可直接寻址的存储单元。
4.1.4 扩展操作码指令格式
扩展操作码(变长操作码)
- 是:地址字段少的指令操作码长,空出的地址位拿去装操作码。
- 不是:不改变指令字长。教材例题里 16 位始终是 16 位。
- 范围:教材例子里三地址指令码短,原因是地址字段挤占,不是使用频率。
前缀码
- 是:任何码字都不是另一码字的前缀的编码。
- 范围:扩展操作码 = 操作码用前缀码编码;性质是唯一可译,一串比特只有一种切分。
扩展窗口
- 是:本层留出的未用编码,供下一层继续扩展。
- 不是:不必是全 1,也不必只留一个。
- 范围:最后一层(零地址)不留窗口,所以 16 位指令字 / 4 位地址的经典分配是 15/15/15/16。
扩展操作码递推
- 是:下层最多条数 =(上层总数 − 上层已用)
。 - 范围:正推反推都用它。“最多几条”与”若还要留扩展则最多几条”差 1。
Kraft 不等式(超纲)
- 是:一组前缀码存在的充要条件
, 表示编码空间用尽。 - 范围:统考不考,作为验算工具用:
必冲突, 还有余量。
变长指令的长度
- 是:由操作码隐含推出——操作码定类型,类型定格式,格式定长度。
- 不是:不需要额外的”长度字段”,一位空间都不占。
- 范围:代价在时序不在空间——取指与译码串行,第 2 条指令的起点要等第 1 条译完。
4.1.5 指令的操作类型
数据传送指令
- 是:把数据从一处搬到另一处,内容不变。
- 范围:一般不影响标志位,因此可插在
CMP和Jcc之间。
LOAD / STORE
- 是:主存与寄存器之间的传送。
- 范围:在 RISC 里是唯一能访存的指令;CISC 无此限制。
PUSH / POP
- 是:压栈 / 弹栈,隐含使用并自动修改 SP。
CMP / TEST
- 是:
CMP做减法、TEST做与,都只置标志位、不保存结果。 - 不是:
CMP不会把差值写回目的操作数。
转移指令
- 是:唯一能写 PC 的一类指令。
- 范围:
JMP/Jcc不存返回地址;CALL存返回地址;TRAP/INT还要存 PSW 并切换特权级。
陷阱指令 TRAP / INT
- 是:程序自愿执行的同步转移,通过中断向量表进入内核。
- 不是:不是异步事件;它是一条指令。
- 范围:用户态主动进入内核态的唯一途径。
IRET
- 是:中断返回,弹出返回地址并恢复 PSW 与特权级。
- 易混:↔
RET(只弹返回地址)。两者不可互换。
程序状态字 PSW
- 是:存放标志位与机器状态的寄存器。
- 范围:由算术逻辑类指令产生、由转移类指令消费,是所有条件分支的传递媒介。
输入输出指令 IN / OUT
- 是:与 I/O 端口交换数据的专用指令。
- 范围:只在 I/O 独立编址的机器上存在;统一编址时用普通访存指令,ISA 里没有 I/O 指令。“没有 I/O 指令”不等于”不能做 I/O”。
4.2.1 指令寻址和数据寻址
指令寻址
- 是:确定下一条指令地址的过程,结果送 PC。
- 易混:↔ 数据寻址(结果送去取操作数)。两者的算法是同一套。
顺序寻址
- 是:
,取指时自动完成。 - 不是:那个
不是 1,而是 。 - 范围:变长指令的
不是常数,要等译码后才确定。
跳跃寻址
- 是:由转移指令给 PC 装一个非顺序值,装完立刻恢复顺序寻址。
- 不是:不是一种”寻址方式”的名字,具体算法仍从十种里挑。
形式地址
- 是:写在指令里的那几位,是计算 EA 的原料。
- 不是:不等于操作数地址——只有直接寻址时两者相等。
有效地址 EA
- 是:算出来的、操作数真正所在的地址。
- 范围:
。立即寻址没有 EA。
寻址特征字段
- 是:指令中说明本条用哪种寻址方式的字段。
- 范围:
位 → 最多 种寻址方式。RISC 常靠操作码隐含,不设此字段。
地址翻译链
- 是:符号 → 形式地址 → EA(逻辑地址) → 线性地址 → 物理地址 → Cache 划分 / 主存译码。
- 范围:相邻两层是”输出→输入”,不是同层的两种做法,因此不能比较优劣、不能互相替代。
4.2.2 常见的数据寻址方式
隐含寻址
- 是:操作数地址隐含在操作码中(如一地址指令的 ACC)。
立即寻址
- 是:
字段里躺的就是操作数本身。 - 不是:没有有效地址;且不访存。
- 范围:立即数是补码,范围
,不是 。
直接寻址
- 是:
,取操作数访存 1 次。 - 范围:寻址范围只有
, 为形式地址位数。
间接寻址
- 是:
,取操作数访存 2 次(多级则每级加 1)。 - 范围:换来两样东西——突破形式地址位数限制、地址可在运行时改(子程序返回、跳转表、函数指针的基础)。
多级间接寻址
- 是:被指向的字里还是地址,需在字中留一位标志说明是否继续。
- 范围:因此一个 32 位字里往往只有 31 位是地址。
寄存器寻址
- 是:
,操作数在寄存器里,访存 0 次。
寄存器间接寻址
- 是:
,访存 1 次。 - 易混:↔ 间接寻址(2 次)。“少一次访存”就是它存在的全部理由。
偏移寻址
- 是:
的统称,含相对、基址、变址三种。 - 范围:三者加法电路完全相同,不是三种硬件。
相对寻址
- 是:
。 - 不是:基准不是当前指令地址,是取指后已增量的 PC(下一条指令地址)。
- 范围:
是带符号补码,转移范围 ;因范围有限,只能做段内转移。
基址寻址
- 是:
,面向系统:程序重定位、多道程序。 - 范围:寄存器是常量(执行期间不变,由 OS/装入程序设定),形式地址是变量。
基址寄存器 BR
- 是:存放程序装入基址的寄存器,可为专用亦可为通用寄存器。
- 不是:不是段寄存器。段寄存器在地址翻译链的下一层。
- 易混:8086 中对应 BX / BP(Base),不是 DS/SS。
变址寻址
- 是:
,面向用户:数组、字符串、循环。 - 范围:形式地址是常量(数组首址),寄存器是变量(下标)——与基址寻址角色互换。
变址寄存器 IX
- 是:存放下标/偏移的寄存器,由用户程序修改。
- 不是:不存数组首地址(首地址在形式地址
里)。 - 易混:8086 中对应 SI / DI(Index)。
比例因子
- 是:x86 的
中的 。 - 范围:直接对应数组元素的字节数,使
arr[i]一步到位。
前变址 / 后变址
- 是:前变址
;后变址 。 - 不是:两者不等价。判据是题目给的括号位置。
堆栈寻址
- 是:
栈顶,由 SP 隐含。 - 范围:硬堆栈(专用寄存器组)不访存,软堆栈(主存)每次访存 1 次。
静态重定位
- 是:装入时由装入程序逐条改写指令里的地址字段,需要重定位表。
- 易混:↔ 动态重定位(改 BR,不动指令);↔ 相对寻址(位移天然相对)。
- 范围:这就是”汇编/链接后那个地址转换过程”的正身。
动态重定位
- 是:由基址寄存器实现,每次访存时硬件做加法,指令字节不变。
- 范围:生效时机是每次访存,静态重定位是装入时一次。
段寄存器
- 是:8086 的 CS/DS/SS/ES,参与
。 - 不是:不是基址寄存器的实现,也不属于任何一种寻址方式。
- 范围:属于分段机制(地址翻译链第 2 层);MIPS 没有段寄存器却照样有基址寻址。
4.3.1 常用汇编指令介绍
Intel 格式
- 是:
mov dst, src,寄存器写eax,内存写[ebp+8]。 - 范围:第一个操作数是目的。
AT&T 格式
- 是:
movl src, dst,寄存器写%eax,立即数写$8,内存写8(%ebp)。 - 范围:第一个操作数是源。判据:有
%$就是 AT&T。两种格式机器码完全相同。
LEA
- 是:把有效地址本身送入寄存器。
- 不是:从不访存;方括号在这里不表示取内容;不改标志位。
- 易混:↔
MOV(取的是内容)。 - 范围:能当算术用,因内存操作数语法本身是
;等效于一条三地址指令;赢在指令条数与执行端口(AGU),不赢在单条延迟。
MOVZ / MOVS
- 是:零扩展 / 符号扩展后再传送。
- 范围:扩展方式必须与原类型的符号性一致,否则值会变(见 2.1.4)。
CF 进位标志
- 是:无符号运算的进位/借位。
- 范围:服务于无符号比较(
ja/jb)。inc/dec不改 CF。
OF 溢出标志
- 是:有符号运算溢出。
- 范围:服务于有符号比较(
jg/jl)。
ZF / SF
- 是:结果为 0 / 结果最高位为 1。
- 范围:一次减法同时置好 CF、OF、ZF、SF——硬件不做选择,硬件提供全部选项。
shl 与 sal
- 是:同一条机器指令的两个助记符(左移时逻辑与算术行为相同)。
- 易混:↔
shr与sar(必须分家:补 0 vs 补符号位)。
4.3.2 选择语句的机器级表示
Jcc 条件转移
- 是:读 PSW 决定是否改 PC 的指令。
- 不是:只读标志位,不改标志位;不必紧跟
cmp(中间可插mov/lea)。 - 范围:
g/l是有符号(greater/less),a/b是无符号(above/below)。
条件取反
- 是:编译器把源码条件取反后跳转,让 then 分支 fall through。
- 范围:读汇编时看到
jle,源码多半写的是>。
跳转表
- 是:
switch的实现,用变址寻址 + 存储器间接寻址一次跳到位。 - 范围:三步——减下界平移 → 无符号
ja挡越界 →jmp [表首址 + 下标×4];case稀疏时表太大,改用级联比较。
无符号越界检查
- 是:减去下界后用
ja比较,一次同时挡住上下两侧越界(下界之外的值减法后成为大无符号数)。 - 不是:用有符号
jg会漏掉下界。
条件传送 CMOV
- 是:按条件决定是否写入目的寄存器,不产生任何转移指令,无分支预测失败。
- 不是:不能用于有副作用、可能出错或开销大的分支——两个分支都会被求值(
p ? *p : 0会无条件解引用)。
4.3.3 循环语句的机器级表示
do-while 骨架
- 是:循环体 → 比较 → 条件后向跳转,整个循环只有一条转移指令。
- 范围:三种循环最终都塌缩到这个骨架。
跳到中间 jump-to-middle
- 是:
-O0下while的翻译——入口一条无条件jmp跳到判断处。 - 易混:↔ 守卫式。入口是无条件
jmp还是条件跳出,是判据。
守卫式 guarded-do
- 是:
-O1+ 下while的翻译——先判一次(守卫),然后整体当do-while。 - 范围:判断代码被复制一份,换来循环体内只剩一条后向分支,利于分支预测。
continue 的落点
- 是:
for里continue跳到update,while里跳到test。 - 范围:这是
for不能机械改写成while的唯一原因;break两者相同。
归纳变量替换
- 是:把
a[i]的地址计算换成一个指针每轮加常量,消掉乘法。 - 范围:结果是汇编里找不到
i;每轮固定增量 = 元素字节数,终止条件变成指针与&a[n]比较。
循环展开
- 是:把若干轮合并成一轮以减少分支与判断。
- 范围:读汇编时看到重复的相同结构、指针一次加 16,不要以为源码写了四遍。
LOOP 指令
- 是:x86 的
ECX--; if(ECX≠0) jump,一条顶三条。 - 范围:编译器几乎从不生成(多数微架构上比
dec+jnz更慢)——CISC 的负面例证。
4.3.4 过程调用的机器级表示
CALL
- 是:
push (下一条指令地址); jmp addr。 - 不是:压入的不是
call自身的地址。 - 易混:↔
JMP(不存返回地址);↔TRAP(还要存 PSW、切特权级)。
RET
- 是:
pop → PC。 - 易混:↔
IRET(还要恢复 PSW 与特权级)。两者不可互换。
返回地址
- 是:存放在栈上(
[ebp+4])。 - 范围:存在栈上,递归才可行;同时它是可写数据,缓冲区溢出改的就是它。
栈帧
- 是:一次函数调用在栈上占据的区域,含参数、返回地址、旧 EBP、保存的寄存器、局部变量。
- 范围:参数区属于调用者的栈帧,由调用者分配、(cdecl 下)由调用者释放。
帧指针 EBP
- 是:指向本帧基址的寄存器,函数执行期间固定不变。
- 易混:↔ ESP(栈顶,随压弹变动)。
- 范围:
[ebp+8]=第一参数、[ebp+4]=返回地址、[ebp]=旧 EBP、[ebp-4]=第一局部变量。这是基址寻址的标准实战:寄存器常量、形式地址变量。
序言 prologue / 尾声 epilogue
- 是:
push ebp; mov ebp,esp; sub esp,N/mov esp,ebp; pop ebp; ret。 - 范围:
leave= 前两条尾声指令的合并。顺序不能乱。
调用者保存寄存器
- 是:
EAXECXEDX(IA-32),语义是”调用之后这几个的值我不保证”。 - 范围:调用后还要用的值,要么放被调用者保存寄存器,要么调用前自己存。
被调用者保存寄存器
- 是:
EBXESIEDIEBP,语义是”调用前后这几个的值不变”。 - 范围:分成两类是为了让双方各存自己真正在用的那些。
调用约定 cdecl / stdcall
- 是:cdecl 调用者清参数栈(支持可变参数如
printf);stdcall 被调用者清栈(ret N,代码小但参数个数固定)。 - 范围:属于 ABI,不属于 ISA。这就是同一颗 CPU 上两套 ABI 不能混用的具体样子。
参数从右往左压栈
- 是:IA-32 的约定。
- 范围:因此第一参数固定落在
[ebp+8],被调用者不必知道参数总数——可变参数函数得以成立。
尾递归优化
- 是:把尾位置的递归调用改写成循环,复用同一个栈帧。
- 范围:优化后递归深度不再增长,不会栈溢出。
4.4.1 复杂指令系统计算机(CISC)
CISC
- 是:指令多而复杂、格式可变、任意指令均可访存、多周期、寄存器少的 ISA 设计倾向。
- 不是:本质不是”指令条数多”,而是单条指令功能复杂 + 任意指令可访存。
- 范围:三条历史动因——主存贵(代码密度)、编译器弱(语义鸿沟)、微程序使扩充廉价。
语义鸿沟
- 是:高级语言语义与机器指令语义之间的差距,CISC 试图靠复杂指令缩小它。
- 范围:今天基本失效——编译器优化能力已超过手写汇编,多条简单指令的调度空间更大。
二八定律(80-20 法则)
- 是:程序 80% 的运行时间只用到约 20% 的指令。
- 范围:RISC 的实测依据——把”复杂指令好不好”从哲学争论变成工程问题。
微操作 μops
- 是:现代 x86 把 CISC 指令译码成的定长、类 RISC 的内部操作。
- 范围:说明 ISA 层与微架构层可以分属两种风格;x86 的 ISA 仍是 CISC。
长度预译码
- 是:超标量 x86 中专门用来切分指令边界的流水级。
- 范围:变长指令的代价的具体形态;RISC 完全不需要这级电路。
复杂指令的价值判据
- 是:看硬件有没有真的为它建一条专用通路。
- 范围:
lea有 AGU 通路 → 编译器大量生成;loop走微码 → 编译器几乎不用。一正一反两个例证。
代码密度
- 是:同一程序编译后占用的存储空间。
- 范围:CISC 唯一保住的优势;收益已从”省主存”转为”省指令 Cache”。ARM 的 Thumb 就是 RISC 反过来学这一条。
4.4.2 精简指令系统计算机(RISC)
RISC
- 是:指令简单且定长、格式统一、寻址方式少、仅 load/store 访存、CPI≈1、寄存器多的设计倾向。
- 不是:精简的不是指令条数,是每条指令的功能。RISC-V 加扩展后指令并不少。
- 范围:全部设计选择都指向同一个词——流水线。
Load/Store 结构
- 是:只有
load/store能访存,其余指令只碰寄存器。 - 范围:真正意义是让每条指令经过相同的流水段,从 ISA 层禁止”中途访存两次”。
- 不是:不等于总访存数据量减少——减少的是中间结果的访存,要靠寄存器多来兑现。
CPI ≈ 1
- 是:流水线满载时的吞吐口径——平均每周期完成一条指令。
- 不是:不是延迟口径。一条指令仍要经过 5 个周期才走完。
寄存器数量 ≥ 32
- 是:Load/Store 结构的必要配套。
- 范围:32 个寄存器要 5 位编号,三地址指令 15 位——与 32 位定长指令字互相配合设计。
指令调度
- 是:编译器重排指令顺序以填满流水线空档、避开数据相关。
- 范围:与寄存器分配、复杂操作合成一起,构成”RISC 把优化重心移到编译器”的具体内容。
延迟槽
- 是:早期 MIPS 让转移指令后一条指令无论转不转都执行。
- 不是:不是所有 RISC 的共同特征——RISC-V 和 ARM 都没有采用。
4.4.3 CISC 和 RISC 的比较
CPU 性能公式
- 是:
。 - 范围:CISC 与 RISC 在三个因子上方向相反(CISC:
少、CPI 大、 长),所以只给一个因子问快慢,答案是”无法判断”。
指令条数 IC
- 是:同一程序编译后的指令总数。
- 不是:不是”指令系统里的指令种类数”。RISC 的
更多(约多 20%~40%)。
“指令条数少”的两种读法
- 是:①指令种类少(RISC 大体对);②同一程序的指令条数少(CISC 对,RISC 错)。
- 范围:统考考的是第二种,因为它出现在性能公式里。
控制器搭配
- 是:CISC↔微程序、RISC↔硬布线,都是典型搭配而非定义。
- 范围:因果强度不对称——RISC→硬布线较硬(指令不简单就没法硬布线),CISC→微程序只是历史便利;现代 x86 简单指令走硬布线、复杂指令走微码。
现代融合
- 是:CISC 内部 RISC 化(μops)、RISC 加扩展(SIMD、Thumb)、共用技术(流水线、超标量、乱序、分支预测、Cache、多核)。
- 范围:共用技术全属微体系结构,与 ISA 风格无关;CISC/RISC 是设计倾向的两端,不是二元标签。
高频范围限定清单
每一条都是”说法 → 它在什么条件下才成立 / 为什么错”。考前扫这一张表。
| 常见说法 | 范围限定 |
|---|---|
| ”Cache 大小、流水线级数属于 ISA” | 错。属于微体系结构,改了老程序照跑 |
| ”调用约定、栈帧布局属于 ISA” | 错。属于 ABI,机器码合法但模块接不上 |
| ”Intel 语法和 AT&T 语法是两种 ISA” | 错。是汇编器约定,机器码完全相同 |
| ”指令字长等于机器字长” | 不一定。取指次数看的是指令字长 ÷ 存储字长 |
| ”单字长指令即指令字长等于机器字长” | 错。是相对存储字长说的 |
| ”指令字长必须是存储字长的整数倍” | 不必。半字长指令合法(一次访存取回两条) |
| “一地址指令一律访存 2 次” | 错。读改写型(INC A)是 3 次 |
| ”零地址指令一定不访存” | 只对硬堆栈成立;软堆栈机取操作数要访存 |
| ”二地址指令执行后第一个操作数保留” | 错。被结果覆盖,这是格式定义的一部分 |
| ”定长指令字必然配定长操作码” | 错。两个维度独立;统考最常考”指令字定长 + 扩展操作码" |
| " | 错。是最多。“最多”与”至少”是两个问题 |
| ”零地址指令不占用操作码编码” | 错。一样要占一个编码 |
| ”扩展操作码会改变指令字长” | 错。指令字长不变,变的是内部分界线 |
| ”三地址指令操作码最短是因为它最常用” | 错。因为地址字段占位最多(真实 ISA 里”高频给短码”是另一条独立理由) |
| “16 位指令字 4 位地址、三地址 15 条 → 二地址最多 15 条” | 错。最多 16 条;留窗口继续扩展才是 15 |
| ”零地址那一层也要留扩展窗口” | 错。下面没有层了,所以是 16 条 |
| ”变长指令需要一个字段标明长度” | 错。长度由操作码隐含推出,不占任何空间 |
| ”变长指令的代价是浪费存储空间” | 反了。它省空间,代价是取指与译码串行 |
”MOV 会影响标志位” | 错。传送类一般不改标志位,LEA 也不改 |
”INC 会改 CF” | 错。inc/dec 不改 CF(保护多精度加法的进位链) |
“CMP 会把差值写回目的操作数” | 错。只置标志位 |
”TRAP 是异步事件” | 错。它是一条指令,同步、程序自愿 |
”RET 和 IRET 可以互换” | 错。IRET 还要恢复 PSW 与特权级 |
”没有 IN/OUT 指令的机器不能做 I/O” | 错。统一编址时用普通访存指令 |
| ”顺序寻址就是 PC 加 1” | 错。增量 = 指令字长 ÷ 编址单位;变长指令下还不是常数 |
| ”跳跃寻址是一种数据寻址方式” | 错。是指令寻址的一种情形,算法仍从十种里挑 |
| ”转移指令的目标地址有专门算法” | 错。复用数据寻址那十种 |
| ”形式地址就是操作数地址” | 只有直接寻址时成立 |
| ”每种寻址方式都要访存” | 错。立即、寄存器寻址不访存 |
| ”立即寻址的有效地址等于 | 错。它没有有效地址 |
| ”立即数范围是 | 错。是补码, |
| “间接寻址访存 1 次” | 错。2 次;多级则每级加 1 |
| ”相对寻址的基准是当前指令地址” | 错。是取指后已增量的 PC(下一条指令地址) |
| “基址寻址中形式地址不变” | 错。恰恰是它在变;不变的是基址寄存器 |
| ”变址寄存器里存数组首地址” | 反了。首地址在形式地址 |
| ”基址与变址的硬件实现不同” | 错。同一套加法;408 分的是语义不是硬件 |
| ”段寄存器是基址寄存器的具体实现” | 错。不在同一层——寻址方式出 EA,分段机制把 EA 变物理地址 |
| ”8086 里 408 的基址寄存器没有对应物” | 错。就是 BX / BP(Base);SI/DI 是 Index |
| ”前变址与后变址等价” | 错。 |
| “程序浮动只能靠基址寄存器” | 错。三种机制:静态重定位(改指令)、基址寻址(改 BR)、相对寻址(位移天然相对) |
“jmp L1(近转移)不是相对寻址” | 错。恰恰是;x86 近转移默认编码成相对形式 |
| ”汇编源码能看出用了哪种寻址方式” | 错。要看汇编器最终选的机器指令编码 |
”LEA 要访存一次取出内容” | 错。从不访存;方括号在 lea 里只是地址表达式语法 |
”LEA 比 ADD 单条延迟更短” | 错。相同或更长;赢在指令条数、执行端口、不改标志位 |
| ”Intel 格式第一个操作数是源” | 错。是目的;AT&T 才是源在前 |
”shr 和 sar 是同一条指令” | 错。左移才不用分家(shl=sal),右移必须分 |
| ”x86 允许两个主存操作数” | 错。必须借道寄存器 |
”源码写 >,机器码跳转也是”大于”类” | 错。编译器把条件取反,跳的是 jle |
”Jcc 必须紧跟 cmp” | 错。中间可插不改标志位的指令(mov/lea) |
“有符号比较用 ja/jb” | 错。那是无符号;有符号用 jg/jl |
| ”跳转表永远优于级联比较” | 错。case 稀疏时表太大 |
| ”跳转表越界检查用有符号比较” | 错。用无符号 ja 才能一次挡住两侧 |
”cmov 可以优化 p ? *p : 0” | 错。两个分支都会被求值,会无条件解引用 |
| ”循环体时间局部性好是因为没有跳转” | 反了。正因为有那条回跳;顺序执行给的是空间局部性 |
”for 和 while 可以机械互换” | 错。continue 的落点不同(for 跳 update);break 相同 |
| ”汇编里找不到循环变量说明代码错了” | 错。归纳变量替换——i 被换成指针 |
”loop 指令比 dec+jnz 快” | 错。多数微架构上更慢,编译器几乎不用 |
”call 压入 call 指令自身的地址” | 错。压入下一条指令的地址 |
| ”返回地址存在专用寄存器里” | 错。存在栈上,否则递归第二层就覆盖第一层 |
| ”EBP 在函数执行期间会变” | 错。固定不变,变的是 ESP |
”push 使 ESP 增大” | 错。栈向低地址生长,ESP 减小 |
| ”每个函数都有栈帧” | 错。叶子函数在 -O2 下常省略 EBP,此时 [ebp+8] 那套失效 |
| ”参数区属于被调用者的栈帧” | 错。属于调用者 |
| ”递归需要专门的硬件支持” | 错。只需要栈 |
| ”调用者保存寄存器在调用后值仍可靠” | 错。那正是”不保证”的一类 |
| ”CISC 必须用微程序控制器” | 错。典型搭配而非定义;现代 x86 简单指令走硬布线 |
| ”RISC 必须用硬布线控制器” | 错。同上(但这个方向的因果更强) |
| “RISC 的指令条数一定比 CISC 少” | 看读法:指令种类大体少;同一程序的指令条数反而多 20%~40% |
| “RISC 每条指令执行延迟 1 个周期” | 错。CPI≈1 是吞吐口径,延迟仍是 5 个周期 |
| ”Load/Store 结构使总访存数据量减少” | 错。减少的是中间结果的访存 |
| ”RISC 代码密度比 CISC 高” | 错。更低,所以指令 Cache 压力更大 |
| ”延迟槽是所有 RISC 的共同特征” | 错。是 MIPS 的历史选择 |
| ”RISC 一定比 CISC 快” | 错。三因子方向相反,必须算乘积 |
| ”只知道 A 机指令条数少就能判断 A 更快” | 错。正确答案是”无法判断" |
| "现代 x86 已经变成 RISC” | 错。ISA 仍是 CISC,只有微架构是 RISC 式 |
| ”超标量、乱序、分支预测是 RISC 专有” | 错。属微体系结构,与 ISA 风格无关 |
链接
- 🏠 返回总览:计算机组成原理第 4 章:指令系统总览
- 📜 原始提问档案:第 4 章 原始提问档案(本地资料)(10 条)
- 📖 上一章名词库:第 3 章名词库
- 📚 权威节号:王道 2026 教材目录