有条件的跳跃

根据标志的状态,CPU 可以执行或忽略跳转。基于标志执行跳转的指令属于 Jcc 的通用名称 - 条件代码 1 上的跳转

同义词和术语

为了提高汇编代码的可读性,英特尔为相同的条件代码定义了几个同义词。例如,jaejnbjnc 都是相同的条件代码 CF = 0

虽然指令名称可能会对何时使用它给出非常强烈的暗示,但唯一有意义的方法是识别需要测试的标志然后适当地选择指令。
然而,英特尔给出了在 cmp 指令之后使用时非常有意义的指令名称。出于本讨论的目的,假设 cmp 在条件跳转之前设置了标志。

相等

如果设置了 *ZF,*则操作数相等,否则它们不同。为了测试相等性,我们需要 ZF = 1

je a_label           ;Jump if operands are equal
jz a_label           ;Jump if zero (Synonym)

jne a_label          ;Jump if operands are NOT equal
jnz a_label          ;Jump if not zero (Synonym)
指令 标志
jejz ZF = 1
jnejnz ZF = 0

比…更棒

对于无符号操作数,如果不需要进位,则目标大于源,即 CF = 0 时。当 CF = 0 时,操作数可能相等,测试 ZF 将消除歧义。

jae a_label      ;Jump if above or equal (>=)
jnc a_label      ;Jump if not carry (Synonym)
jnb a_label      ;Jump if not below (Synonym)

ja a_label       ;Jump if above  (>)
jnbe a_label     ;Jump if not below and not equal (Synonym)
指令 标志
jaejncjnb CF = 0
jajnbe CF = 0,ZF = 0

对于带**符号的操作数,**我们需要检查 SF = 0 ,除非有符号溢出,在这种情况下产生的 SF 反转。由于 *OF = 0,*如果没有发生签名溢出,否则为 1,我们需要检查 SF = OF

ZF 可用于实施严格/非严格测试。

jge a_label      ;Jump if greater or equal (>=)
jnl a_label      ;Jump if not less (Synonym)

jg a_label       ;Jump if greater (>)
jnle a_label     ;Jump if not less and not equal (Synonym)
指令 标志
jgejnl SF = OF
jgjnle SF = OF,ZF = 0

少于

这些使用上述的反转条件。

jbe a_label      ;Jump if below or equal (<=)
jna a_label      ;Jump if not above (Synonym)

jb a_label       ;Jump if below (<)
jc a_label       ;Jump if carry (Synonym)
jnae a_label     ;Jump if not above and not equal (Synonym)

;SIGNED 

jle a_label      ;Jump if less or equal (<=)
jng a_label      ;Jump if not greater (Synonym)

jl a_label       ;Jump if less (<)
jnge a_label     ;Jump if not greater and not equal (Synonym)
指令 标志
jbejna CF = 1 或 ZF = 1
jbjcjnae CF = 1
jlejng SF != OF 或 ZF = 1
jljnge SF != OF

具体标志

可以使用 j<flag_name> 单独测试每个标志,其中 flag_name 不包含尾随 F (例如 CFCPFP )。

以前未涉及的其余代码是:

指令 标志
js SF = 1
jns SF = 0
jo OF = 1
jno OF = 0
jpjpe(e = even) PF = 1
jnpjpo(o = odd) PF = 0

还有一个条件跳转(额外的一个)

一个特殊的 x86 条件跳转不会测试标志。相反,它测试 cxecx 寄存器的值(基于当前 CPU 地址模式为 16 或 32 位),并且当寄存器包含零时执行跳转。

该指令设计用于在类似于 rep 的指令之前或者在 loop 循环之前验证计数器寄存器(cx/ecx)。

jcxz  a_label   ; jump if cx (16b mode) or ecx (32b mode) is zero
jecxz a_label   ; synonym of jcxz (recommended in source code for 32b target)
指令 注册(不是标志)
jcxzjecxz cx = 0(16b 模式)
jcxzjecxz ecx = 0(32b 模式)

1 或类似的东西。