汇编——比较指令和条件跳转指令

CMP 比较指令

格式
CMP 操作数1, 操作数2
原理
等价于 操作数1−操作数2,不保存运算结果,仅修改CF、ZF、OF、AF、PF、SF所有状态标志位
作用
配合条件跳转指令做判断,对应高级语言 if/else 逻辑
常用组合(无符号数比较)

指令含义判定条件英文释义
JE / JZ相等则跳转ZF = 1Equal / Zero
JNE / JNZ不相等则跳转ZF = 0Not Equal / Not Zero
JB / JC低于(小于)则跳转CF = 1Below / Carry
JNB / JNC不低于(大于等于)则跳转CF = 0Not Below / Not Carry
JA高于(大于)则跳转CF=0 且 ZF=0Above
JNA不高于(小于等于)则跳转CF=1 或 ZF=1Not Above

补充别名: JB = JNAE(不高于等于);JNB = JAE(高于等于)

TEST 测试指令

格式
TEST 操作数1, 操作数2
原理
执行 按位与 (AND) 运算,不修改两个操作数本身,仅刷新 SF、ZF、PF,强制置 CF=0、OF=0
典型用法

  1. 检测某一个二进制位是否为 1
    TEST AL, 01H ; 检测AL最低位 //汇编中写注释用;
    ; 最低位=1 → 与运算结果≠0 → ZF=0
    ; 最低位=0 → 与运算结果=0 → ZF=1
  2. 判断寄存器是否为 0
    TEST EAX, EAX ; 自身按位与
    ; EAX=0 → ZF=1;EAX≠0 → ZF=0
  3. 判断正负:结合 SF 符号位,判断数据正负

条件跳转指令总表(按标志位分类)

跳转指令紧跟 CMP/TEST/ 运算指令,根据前序指令产生的标志位判断是否跳转

  1. 基于 ZF 零标志位
    ● JZ / JE:ZF=1,结果为 0 / 两数相等,跳转
    ● JNZ / JNE:ZF=0,结果非 0 / 两数不等,跳转
  2. 基于 CF 进位 / 借位标志位(多用于无符号数)
    ● JC / JB / JNAE:CF=1,有进位 / 借位 / 前者更小,跳转
    ● JNC / JNB / JAE:CF=0,无进位 / 借位 / 前者更大或相等,跳转
  3. 基于 OF 溢出标志位(多用于有符号数)
    ● JO:OF=1,运算溢出,跳转
    ● JNO:OF=0,无溢出,跳转
  4. 基于 SF 符号标志位(判断正负)
    ● JS:SF=1,结果为负数,跳转
    ● JNS:SF=0,结果为非负数(正数 / 0),跳转
  5. 基于 PF 奇偶标志位
    ● JP / JPE:PF=1,结果低 8 位中二进制1的个数为偶数,跳转
    ● JNP / JPO:PF=0,结果低 8 位中二进制1的个数为奇数,跳转

JMP 无条件跳转

格式
JMP 目标地址/标签
说明
不检测任何标志位,直接跳转到指定位置执行代码,对应高级语言 goto
分类:短跳转、近跳转、远跳转,日常调试最常用短 / 近跳转

区分

  1. CMP vs TEST
    ○ CMP:做减法,用于数值大小、相等判断
    ○ TEST:做按位与,用于位检测、判零、判正负
  2. 有符号数 vs 无符号数跳转选择
    ○ 无符号数比大小:优先用 JA/JB/JNA/JNB(依赖 CF、ZF)
    ○ 有符号数比大小:使用 JG/JL 等专用指令(依赖 SF、OF 组合)
  3. 顺序要求:必须先执行 CMP/TEST/ 算术运算 修改标志位,再使用跳转指令,中间不能穿插会改变标志位的指令