x86 汇编:条件跳转与标志位
汇编里的分支依赖标志位。
cmp
cmp rax, rbx
je equal
cmp 本质上做减法但不保存结果,只更新标志位。
test
test rax, rax
jz zero
test 常用于判断寄存器是否为 0。
常见跳转
je/jz:相等或零。jne/jnz:不等或非零。jg/jl:有符号比较。ja/jb:无符号比较。
标志位不是普通变量
cmp 和 test 会影响标志寄存器,后面的条件跳转读取这些标志。它们之间通常挨得很近:
cmp eax, 10
jge large_enough
如果中间插入了会修改标志位的指令,跳转含义就会改变。
有符号和无符号要分清
jg、jl 用于有符号比较;ja、jb 用于无符号比较。C++ 里 int 和 unsigned int 混用时,编译器生成的跳转也可能不同。
这也是为什么 C++ 中有符号和无符号混合比较会产生警告。到了汇编层面,这个差异会变成不同的条件跳转。
阅读分支
读反汇编时,可以先把条件跳转翻译成高级语言:
如果 eax >= 10,跳到 large_enough
否则继续执行下面的代码
这样比逐条死记指令更容易理解控制流。
评论
...正在读取评论。