80x86汇编与C语言-2
看清每行 C 代码背后的寄存器、栈帧与调用约定
按 空格/→ 演示下一步
全部页面点击任意一页,跳回舞台从这页播放
80x86汇编与C语言-2
看清每行 C 代码背后的寄存器、栈帧与调用约定
条件码
前面讲过算术指令会改写通用寄存器——其实CPU还多做一步:把这次运算的关键属性(结果是否为0、是否进位、是否溢出)编码成一组1-bit标志,塞进FLAGS寄存器的特定位。这就是条件码。
验货后自动打勾/打叉,收件人只读不改——ALU隐式写,Jcc只读消费
比较指令与测试指令
上一页讲了条件码是CPU的'小本本',但谁来填这本子?直接用SUB、AND会真的改数据——我们不想要这个副作用。CMP和TEST就是'只算不算、只测不存'的专用指令。
指针告诉你大小关系,但两个数本身没被移动——纯'窥探',无副作用
读取条件码指令-1
CMP 和 TEST 帮你把比较结果写进了标志位,但标志位本身是隐式的,C 语言没法直接拿。这页要解决的就是:怎么把「条件成立与否」取出来,变成程序能用的 0/1。
CMP 是体检,把指标写进报告(标志位);SETcc 是看报告,只填结论(0/1),不重做体检
读取条件码指令-2
上一页讲的 SETcc、Jcc 都靠分支跳转,但现代 CPU 流水线最怕分支猜错。还有第三种读条件码的指令 CMOVcc——它不跳转,把两条路的结果都算好,按条件挑一个留下。
两条路都先铺好,走到路口按条件牌选一条;Jcc 是先猜一条走,猜错要回头
x86-64下的读取条件码指令
上两页讲了 SET 写字节、JMP 改流程,都是'有条件地做某事'。还有第三条路——'条件决定选哪个值',这就是 CMOV 条件传送指令。
扳道工看信号旗决定火车走哪条轨道;CMOV 看条件码决定把哪个值送到目标寄存器
跳转指令
前面用 set 指令把条件码「读」出来,但光读不行动没用。跳转指令才是把决策落到执行顺序上的工具:该不该换行、去哪一段,全看条件码的脸色。
角色状态=条件码;岔路=跳转目标;j* 按状态选路,jmp 不管状态直接跳
条件移动指令
跳转指令一旦预测失败,流水线要清空重来——代价惨烈。条件移动干脆不预测:先两边都算完,按条件码挑结果,流水线一根道走到底。
符合条件才放行(搬入),否则就地留下(不搬);队伍没换队形——控制流没分叉
本节要点
- ✓比较与测试只更新条件码,不改源操作数
- ✓跳转依据条件码选择路径,适合稀疏条件
- ✓条件传送无分支,但受值可用性约束
- ✓x86-64下32位写条件码指令仅设置低8位
- ✓同一逻辑条件可由多条互补条件码指令实现
课后思考
先自己琢磨,再对照参考答案。三题分别对应回顾、应用与迁移。
参考答案`cmp` 不写回结果,只置条件码,避免污染目的寄存器;语义清晰,也利于编译器优化。
参考答案看场景:分支预测难时条件传送更快;适合简单赋值、计算量小、结果需多处使用的情形。
参考答案RISC-V没有标志位,比较结果本身就是值;用`slt`等指令产生0/1,再用分支或掩码合并结果。