x86 汇编跳转指令

JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等

跳转指令分为三类:无条件跳转、基于寄存器值跳转、以及基于标志位的条件跳转

无条件跳转

JMP: 直接无条件跳转到指定位置

JMP label

基于寄存器值跳转

img

JCXZ:若 CX 寄存器的值为 0, 则跳转

JCXZ label

JECXZ:若 ECX 寄存器的值为 0, 则跳转

JECXZ label

基于标志位的条件跳转

条件跳转指令依据 EFLAGS 寄存器的特定标志位设置状态进行跳转, 常见标志位有

  • CF (进位标志)
  • PF (奇偶标志)
  • ZF (零标志)
  • SF (符号标志)
  • OF (溢出标志)

img

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 时跳转)

JEJZ 的区别

在 x86 汇编中, JE(Jump if Equal)和 JZ(Jump if Zero)本质上是相同的指令, 指向同一个操作码。它们的功能完全一致, 区别仅在于它们的语义使用场景不同

功能

  • JE: 跳转到目标地址, 如果标志寄存器(EFLAGS)的 ZF(Zero Flag) 位为 1
  • JZ: 跳转到目标地址, 如果标志寄存器的 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)的设置条件

  1. 比较(CMP): 如果两个操作数相等, ZF 会被置为 1
  2. 减法(SUB): 如果结果为 0, ZF 会被置为 1
  3. 按位操作: 一些按位运算(如 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 位

附件

指令对标志寄存器的影响总结5.docx (PDF 版本)

指令对标志寄存器的影响总结5


原文

学 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

最后更新于 2020-03-13
使用 Hugo 构建
主题 StackJimmy 设计