首页/计算机组成原理/04-instruction/选择结构的机器级表示 🔗 在 Obsidian 中打开
计算机组成原理 · 04-instruction

选择结构的机器级表示

重要度 ⭐⭐⭐⭐指令系统选择结构分支条件跳转机器级表示
速查
选择结构 = CMP/TEST 设条件码 + Jcc 条件跳转。有符号比较看 SF/OF(JG/JL),无符号比较看 CF(JA/JB);switch 在 case 连续密集时用跳转表做到 $O(1)$。

速查

项目
对应高级语言if-elseswitch-case
机器级实现条件码 + 条件跳转指令(条件分支)
关键标志位CF(进位)、ZF(零)、SF(符号)、OF(溢出)
核心指令CMP/TEST + 条件跳转指令(Jcc

核心概念

高级语言中的选择结构(if-elseswitch)在机器级通过条件码寄存器 + 条件跳转指令实现。

实现流程

  1. 先执行比较指令(如 CMP),该指令做减法但不保存结果,只设置条件码 / 标志位
  2. 根据条件码的值,执行条件跳转指令(Jcc)决定是否跳转
  3. 条件满足则跳转到目标地址执行,否则顺序执行下一条指令

if-else 的机器级模式

    CMP  R1, R2      ; 比较,设置条件码
    Jcc  L1           ; 条件不满足则跳到 else 分支
    ; then 分支代码
    JMP  L2           ; 跳过 else 分支
L1: ; else 分支代码
L2: ; 后续代码

switch 的机器级实现

  • 跳转表(Jump Table):当 case 值连续时,用跳转表实现 $O(1)$ 分支。表中存储各 case 的入口地址。
  • 条件分支链:当 case 值稀疏时,退化为 if-else 链,逐个比较。
switch 的两条实现路线 跳转表(case 连续密集) addr = base + (v-min)*size 一次索引直达目标,O(1) 代价:需要一张地址表 分支链(case 稀疏) CMP → Jcc → CMP → Jcc … 逐个比较,O(n) 代价:分支数多时变慢
图:case 值是否连续密集,决定编译器选跳转表还是分支链。

关键性质

标志位名称含义设置条件
CF进位标志无符号运算是否产生进位/借位加法产生进位或减法产生借位时 $CF=1$
ZF零标志结果是否为零运算结果为 0 时 $ZF=1$
SF符号标志结果的符号(最高位)结果为负数时 $SF=1$
OF溢出标志有符号运算是否溢出有符号数溢出时 $OF=1$
条件跳转指令含义条件
JE / JZ相等 / 为零跳转$ZF=1$
JNE / JNZ不相等 / 非零跳转$ZF=0$
JG / JNLE大于(有符号)$ZF=0$ 且 $SF=OF$
JL / JNGE小于(有符号)$SF \neq OF$
JA / JNBE大于(无符号)$CF=0$ 且 $ZF=0$
JB / JNAE小于(无符号)$CF=1$

常见考法

考法解题套路
给定 C 代码写出汇编CMP 比较 → 条件跳转 → 分支代码
根据条件码判断跳转执行 CMP 后分析 ZF/SF/OF/CF 的值
switch 的跳转表实现理解跳转表的索引方式:地址 = 表基址 + (case 值 $- min) \times$ 表项大小
有符号 vs 无符号比较有符号用 SF/OF 判断(JG/JL),无符号用 CF 判断(JA/JB)

易错点

⚠️ 高频陷阱
  • CMP 是隐含的减法CMP A, B 计算 $A-B$ 并设置标志位,但不保存结果。
  • 有符号和无符号条件跳转不同:JG/JL 用于有符号数,JA/JB 用于无符号数。混用会导致错误。
  • OF 和 CF 的区别:OF 检测有符号溢出,CF 检测无符号溢出/借位。
  • switch 优化条件:跳转表要求 case 值密集且连续,否则退化为 if-else 链。
  • JMP 是无条件跳转if-else 中 then 分支结束后需要 JMP 跳过 else 分支。

核心结论

必背
  1. 选择结构的机器级实现 = CMP(设标志位) + Jcc(条件跳转)
  2. switch 的跳转表实现效率为 $O(1)$,前提是 case 值连续。
  3. 有符号比较和无符号比较使用不同的条件跳转指令。
  4. 条件码寄存器(CF/ZF/SF/OF)是实现分支的关键硬件机制。

记忆卡片

CMP 指令的作用?
做减法并设置条件码,不保存结果。
有符号比较用哪些跳转?
JG、JL、JGE、JLE。
无符号比较用哪些跳转?
JA、JB、JAE、JBE。
switch 何时用跳转表?
case 值连续且密集时。
$ZF=1$ 表示什么?
运算结果为零(两数相等)。
JL 的判定条件?
$SF \neq OF$(有符号小于)。

交互动画 · CMP 置标志位 → Jcc 判跳

操作数 A5 操作数 B3 CMPA−B 运算结果2 标志位 CF0 ZF0 SF0 OF0 条件跳转 JE / JZ JNE / JNZ JG(有符号>) JL(有符号<) JA(无符号>) JB(无符号<)
选择一个比较场景,观察条件码如何决定分支走向
绿色边框 = 该条件跳转会被执行(taken)
示意图:同一组标志位,有符号指令看 SF/OF无符号指令看 CF——最后一个场景两者结论相反,正是易错点所在。

相关知识点

loop-machine-level procedure-call-machine-level addressing-modes

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