跳转指令分为三类:无条件跳转、基于寄存器值跳转、以及基于标志位的条件跳转
无条件跳转
JMP: 直接无条件跳转到指定位置
JMP label
基于寄存器值跳转
JCXZ:若 CX
寄存器的值为 0
, 则跳转
JCXZ label
JECXZ:若 ECX
寄存器的值为 0
, 则跳转
JECXZ label
基于标志位的条件跳转
条件跳转指令依据 EFLAGS
寄存器的特定标志位设置状态进行跳转, 常见标志位有
- CF (进位标志)
- PF (奇偶标志)
- ZF (零标志)
- SF (符号标志)
- OF (溢出标志)
JE ; 等于则跳转 同 JZ
JNE ; 不等于则跳转 同 JNZ
JZ ; 为 0 则跳转
JNZ ; 不为 0 则跳转
JS ; 为负则跳转
JNS ; 不为负则跳转
JC ; 进位则跳转
JNC ; 不进位则跳转
JO ; 溢出则跳转
JNO ; 不溢出则跳转
JA ; 无符号大于则跳转
JNA ; 无符号不大于则跳转
JAE ; 无符号大于等于则跳转 同 JNB
JNAE ; 无符号不大于等于则跳转 同 JB
JG ; 有符号大于则跳转
JNG ; 有符号不大于则跳转
JGE ; 有符号大于等于则跳转 同 JNL
JNGE ; 有符号不大于等于则跳转 同 JL
JB ; 无符号小于则跳转
JNB ; 无符号不小于则跳转
JBE ; 无符号小于等于则跳转 同 JNA
JNBE ; 无符号不小于等于则跳转 同 JA
JL ; 有符号小于则跳转
JNL ; 有符号不小于则跳转
JLE ; 有符号小于等于则跳转 同 JNG
JNLE ; 有符号不小于等于则跳转 同 JG
JP ; 奇偶位置位则跳转
JNP ; 奇偶位清除则跳转
JPE ; 奇偶位相等则跳转 同 JP
JPO ; 奇偶位不等则跳转 同 JNP
具体指令
指令 | 条件描述 |
---|---|
JE / JZ |
等于/为零 (ZF=1 时跳转) |
JNE / JNZ |
不等于/非零 (ZF=0 时跳转) |
JA / JNBE |
大于/不低于或等于 (CF=0 且 ZF=0 时跳转) |
JAE / JNB |
大于或等于/不低于 (CF=0 时跳转) |
JB / JNAE |
小于/不高或等于 (CF=1 时跳转) |
JBE / JNA |
小于或等于/不高 (CF=1 或 ZF=1 时跳转) |
JG / JNLE |
大于/不小或等于 (ZF=0 且 SF=OF 时跳转) |
JGE / JNL |
大于或等于/不小于 (SF=OF 时跳转) |
JL / JNGE |
小于/不大于或等于 (SF≠OF 时跳转) |
JLE / JNG |
小于或等于/不大于 (ZF=1 或 SF≠OF 时跳转) |
JS |
符号标志为负 (SF=1 时跳转) |
JNS |
符号标志为正 (SF=0 时跳转) |
JO |
溢出标志为 1 (OF=1 时跳转) |
JNO |
溢出标志为 0 (OF=0 时跳转) |
JC |
进位标志为 1 (CF=1 时跳转) |
JNC |
进位标志为 0 (CF=0 时跳转) |
JP / JPE |
奇偶标志为 1 (偶数个 1) (PF=1 时跳转) |
JNP / JPO |
奇偶标志为 0 (奇数个 1) (PF=0 时跳转) |
JE
和 JZ
的区别
在 x86 汇编中, JE
(Jump if Equal)和 JZ
(Jump if Zero)本质上是相同的指令, 指向同一个操作码。它们的功能完全一致, 区别仅在于它们的语义使用场景不同
功能
JE
: 跳转到目标地址, 如果标志寄存器(EFLAGS)的 ZF(Zero Flag) 位为 1JZ
: 跳转到目标地址, 如果标志寄存器的 ZF(Zero Flag) 位为 1
换句话说, 两者的核心是条件跳转依赖于 Zero Flag 的值, 当 Zero Flag 为 1 时跳转
语义区别
虽然它们是等效的, 但在程序编写中, 使用的指令名称会根据程序员的意图和上下文有所不同
-
JE(Jump if Equal)
-
用于表示两值相等的场景, 通常在比较(如
CMP
)之后使用 -
示例
CMP EAX, EBX ; 比较 EAX 和 EBX JE EqualLabel ; 如果相等则跳转
-
-
JZ(Jump if Zero)
-
用于检查结果是否为零, 通常在减法或按位运算等操作之后使用
-
示例
SUB EAX, EBX ; EAX 减去 EBX JZ ZeroLabel ; 如果结果为零则跳转
-
使用习惯总结
JE
强调逻辑上的 “相等”JZ
强调结果值为零
虽然它们最终执行的效果是一样的, 使用哪一个主要取决于代码上下文和可读性
扩展知识
ZF(Zero Flag)的设置条件
- 比较(CMP): 如果两个操作数相等, ZF 会被置为 1
- 减法(SUB): 如果结果为 0, ZF 会被置为 1
- 按位操作: 一些按位运算(如
AND
)的结果为 0 时, ZF 也会被置为 1
影响标志位的汇编指令
加法指令:ADD、ADC、INC、XADD
除了 INC 不影响 CF 标志位外, 都影响条件标志位
CF、ZF、SF、OF
CF 最高位是否有进位
DF 若两个操作数符号相同而结果符号与之相反 OF=1, 否则 OF=0
减法指令:SUB、SBB、DEC、NEG、CMP、CMPXCHG、CMPXCHG8B
前六种除了 DEC 不影响 CF 标志外都影响标志位。CMPXHG8B 只影响 ZF
CF 说明无符号数相减的溢出, 同时又确实是被减数最高有效位向高位的借位
OF 位则说明带符号数的溢出
无符号运算时, 若减数>被减数, 有借位 CF=1, 否则 CF=0
OF 若两个数符号相反, 而结果的符号与减数相同则 OF=1. 否则 OF=0
乘法指令:MUL、IMUL
MUL:如果乘积高一半为 0, 则 CF 和 OF 位均为 0, 否则 CF 和 OF 均为 1
IMUL:如果高一半是低一半符号的扩展, 则 CF 位和 OF 位均为 0, 否则就均为 1
除法指令:DIV、IDIV
对所有条件位均无定义
逻辑指令:AND、OR、NOT、XOR、TEST
NOT 不影响标志位, 其余 4 种 CF、OF、置 0, AF 无定义, SF、ZF、PF 位看情况而定
定位扫描指令:BSF正向位扫描、BSR反向位扫描
影响 ZF 位
附件
原文
学 Win32 汇编[28] - 跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等
汇编跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等
x86 Assembly Guide