• 汇编语言条件跳转指令汇总

    x86 指令集包含大量的条件跳转指令。它们能比较有符号和无符号整数,并根据单个 CPU 标志位的值来执行操作。条件跳转指令可以分为四个类型:

    • 基于特定标志位的值跳转
    • 基于两数是否相等,或是否等于(E)CX 的值跳转
    • 基于无符号操作数的比较跳转
    • 基于有符号操作数的比较跳转

    下表展示了基于零标志位、进位标志位、溢出标志位、奇偶标志位和符号标志位的跳转。

    助记符 说明 标志位/寄存器 助记符 说明 标志位/寄存器
    JZ 为零跳转 ZF=1 JNO 无溢出跳转 OF=0
    JNZ 非零跳转 ZF=0 JS 有符号跳转 SF=1
    JC 进位跳转 CF=1 JNS 无符号跳转 SF=0
    JNC 无进位跳转 CF=0 JP 偶校验跳转 PF=1
    JO 溢出跳转 OF=1 JNP 奇校验跳转 PF=0

    1) 相等性的比较

    下表列出了基于相等性评估的跳转指令。有些情况下,进行比较的是两个操作数;其他情况下,则是基于 CX、ECX 或 RCX 的值进行跳转。表中符号 leftOp 和 rightOp 分别指的是 CMP 指令中的左(目的)操作数和右(源)操 作数:

    助记符 说明
    JE 相等跳转 (leftOp=rightOp)
    JNE 不相等跳转 (leftOp M rightOp)
    JCXZ CX=0 跳转
    JECXZ ECX=0 跳转
    JRCXZ RCX=0 跳转(64 位模式)

    CMP leftOp,rightOp

    操作数名字反映了代数中关系运算符的操作数顺序。比如,表达式 X< Y 中,X 被称为 leftOp,Y 被称为 rightOp。

    尽管 JE 指令相当于 JZ(为零跳转),JNE 指令相当于 JNZ(非零跳转),但是,最好是选择最能表明编程意图的助记符(JE 或 JZ),以便说明是比较两个操作数还是检查特定的状态标志位。

    下述示例使用了 JE、JNE、JCXZ 和 JECXZ 指令。仔细阅读注释,以保证理解为什么条件跳转得以实现(或不实现)。

    示例 1:

    mov edx, 0A523h
    cmp edx, 0A523h
    jne L5                       ;不发生跳转
    je L1                         ;跳转

    示例 2:

    mov bx,1234h
    sub bx,1234h
    jne L5                       ;不发生跳转
    je L1                         ;跳转

    示例 3:

    mov ex, 0FFFFh
    inc ex
    jexz L2                      ;跳转

    示例4:

    xor ecx,ecx
    jeexz L2                   ;跳转

    2) 无符号数比较

    基于无符号数比较的跳转如下表所示。操作数的名称反映了表达式中操作数的顺序(比如 leftOp < rightOp)。下表中的跳转仅在比较无符号数值时才有意义。有符号操作数使用不同的跳转指令。

    助记符 说明 助记符 说明
    JA 大于跳转(若 leftOp > rightOp) JB 小于跳转(若 leftOp < rightOp)
    JNBE 不小于或等于跳转(与 JA 相同) JNAE 不大于或等于跳转(与 JB 相同)
    JAE 大于或等于跳转(若 leftOp ≥ rightOp) JBE 小于或等于跳转(若 leftOp ≤ rightOp)
    JNB 不小于跳转(与 JAE 相同) JNA 不大于跳转(与 JBE 相同)

    3) 有符号数比较

    下表列岀了基于有符号数比较的跳转。下面的指令序列展示了两个有符号数值的比较:

    助记符 说明 助记符 说明
    JG 大于跳转(若 leftOp > rightOp) JL 小于跳转(若 leftOp < rightOp)
    JNLE 不小于或等于跳转(与 JG 相同) JNGE 不大于或等于跳转(与 JL 相同)
    JGE 大于或等于跳转(若 leftOp ≥ rightOp) JLE 小于或等于跳转(若 leftOp ≤ rightOp)
    JNL 不小于跳转(与 JGE 相同) JNG 不大于跳转(与 JLE 相同)

    mov al, +127             ;十六进制数值 7Fh
    cmp al, -128              ;十六进制数值 80h
    ja Is Above                ;不跳转,因为 7Fh < 80h
    jg IsGreater               ;跳转,因为 +127 > -128

    由于无符号数 7Fh 小于无符号数 80h,因此,为无符号数比较而设计的 JA 指令不发生跳转。另一方面,由于 +127 大于 -128,因此,为有符号数比较而设计的 JG 指令发生跳转。

    对下面的代码示例,阅读注释,以保证理解为什么跳转得以实现(或不实现):

    示例 1:

    mov edx,-1
    cmp edx, 0
    jnl  L5                   ;不发生跳转(-1 ≥ 0 为假)
    jnle L5                  ;不发生跳转(-1 > 0 为假)
    jl L1                      ;跳转(-1 < 0 为真)

    示例 2:

    mov bx,+ 32
    cmp bx,-35
    jng L5                 ;不发生跳转( + 32 ≤ -35 为假)
    jnge L5               ;不发生跳转( + 32 < -35 为假)
    jge L1                 ;跳转( + 32 ≥ -35 为真)

    示例 3:

    mov ecx, 0
    cmp ecx, 0
    jg L5                     ;不发生跳转(0 > 0 为假)
    jnl L1                    ;跳转(0 ≥ 0 为真)

    示例 4:

    mov ecx, 0
    cmp ecx, 0
    jl L5                      ;不发生跳转(0 < 0 为假)
    jng L1                   ;跳转(0 ≤ 0 为真)

更多...

加载中...