JCC 条件跳转总述
1.JCC 是一组条件跳转指令,区别于无条件JMP:
JMP:直接改写 EIP,必定跳转
JCC:先读取 EFLAGS 标志位状态,满足条件才改 EIP 跳转,不满足则顺序执行下一条指令
2.触发来源:加减运算、CMP 比较、移位等指令都会自动刷新 EFLAGS 对应标志位
EFLAGS 关键标志位详解
- CF 进位标志(第 0 位,无符号数专用)
规则:无符号加减产生最高位进位 / 借位 → CF=1;无进位借位 → CF=0
用途:判断无符号数溢出、无符号大小对比(JA/JB/JBE/JAE)
例:0xFF + 1,8 位无符号溢出,CF=1 - PF 奇偶标志(第 2 位)
只看结果低 8 位里二进制 1 的总数:偶数个 1 → PF=1;奇数个 1 → PF=0
日常汇编逆向极少使用,多用于串口、校验场景 - AF 辅助进位(第 4 位)
仅看二进制第 3 位向第 4 位是否进位 / 借位,有则 AF=1
专门给 BCD 十进制调整指令用,普通数值运算几乎不用 - ZF 零标志(第 6 位)
运算 / 比较结果等于 0 → ZF=1;结果非 0 → ZF=0
高频搭配:CMP a,b后,ZF=1 代表 a==b(JE/JZ 跳转)
例1:判断2个值是否相等
cpp
MOV EAX,100
MOV ECX,100
CMP EAX,ECX(CMP指令相当于SUB指令,但是相减的结果并不保存到第一个操作数中)
例2:判断某个值是否为0
cpp
TEST EAX,EAX
(TEST指令相当于AND指令,但是与的结果并不保存到第一个操作数中)
- SF 符号标志(第 7 位)
复制运算结果最高位;有符号数最高位是1,负数SF=1;最高位是0,正数 SF=0 - OF 溢出标志(第 11 位,有符号数专用)
有符号正数 + 正数变负数、负数 + 负数变正数,属于数值溢出 → OF=1
无符号溢出看 CF,有符号溢出看 OF,二者互不干扰 - DF 方向标志(第 10 位)
方向标志DF用来决定在串操作指令执行时有关指针寄存器发生调整的方向
在微机的指令系统中,还提供了专门的指令来改变标志位DF的值
控制串指令(MOVS/STOS/LODS)ESI、EDI 增减:
CLD → DF=0,地址递增
STD → DF=1,地址递减
溢出和进位的区别:
溢出(Overflow):溢出发生在有符号数的运算中
当有符号操作结果超出了有符号数的表示范围时,即结果无法用有限位数表示时,会发生溢出
例如,在有符号的加法或减法中,如果操作结果超出了数据类型所能表示的范围,就会发生溢出,溢出标志位(OF)用于指示溢出的发生与否,溢出可以导致程序执行错误的结果
进位(Carry):进位通常发生在无符号数的运算中
当无符号操作中产生了超过表示范围的结果时,会发生进位
例如,在无符号的加法中,如果操作结果超出了数据类型所能表示的最大值,就会发生进位,进位标志位(CF)用于指示进位的发生与否,进位标志位在无符号数的运算和一些位级操作(如位逻辑运算)中也有其他用途 FC+05
CMP 指令配套逻辑
CMP op1,op2 本质等价 SUB op1,op2,只修改标志位、不保存减法结果
专门用来对比两个数大小、相等,为 JCC 提供判断依据
无符号数对比指令(JA / JBE 示例)
JA(高于则跳转):条件 CF=0 且 ZF=0(a > b)
JBE(低于等于则跳转):条件 CF=1 或 ZF=1(a ≤ b)
配套全家无符号:
JB/JC:CF=1(小于)
JAE/JNC:CF=0(大于等于)
有符号数对比常用指令(依托 SF、OF、ZF)
JG:大于(SF=OF、ZF=0)
JL:小于(SF≠OF)
JGE:大于等于(SF=OF)
JLE:小于等于(SF≠OF 或 ZF=1) 相等统一用 JE/JZ(ZF=1);不等 JNZ/JNE(ZF=0)
执行流程示例
cpp
mov al, 0xFF
add al, 1 ; 无符号溢出,CF=1、ZF=1
jc Label1 ; JC等价JB,CF=1满足,跳Label1
mov eax,5
cmp eax,3
ja Label2 ; CF=0 ZF=0,5>3,跳转Label2
区分
无符号大小:看 CF+ZF,指令 JA/JB/JBE/JAE
有符号大小:看 SF^OF+ZF,指令 JG/JL/JGE/JLE
相等判断只看 ZF:JE/JZ;不等 JNZ/JNE
JCC 不满足条件时,CPU 不修改 EIP,顺序往下执行