文章目录
什么是JCC指令
- 能够修改EIP寄存器的值
- 不同于之前的JMP、CALL、RET
- 通过标志寄存器中的值判断是否跳转
EFLAGS标志寄存器
- 要想了解JCC指令就要了解标志寄存器,这是它各自代表的功能
CF(0 bit)[Carry flag]
若算数产生的结果在最高有效位发生进位或借位则将其置1,反之清0。
这个标志常用来指示无符号整数运算的溢出状态。
例:
MOV AL,0XFE //向AL寄存器中写入0XFF
ADD AL,2 //向AL寄存器的值+2
运行结果:
PF(2 bit)[Parity flag]
如果结果的最低有效字节包含1的个数为偶数,该位置1,否则清零,这也就是大家把它叫做奇偶校验位的原因。
可以用来进行奇偶校验检查
例:我们现在把113这个数字存到AX里,再给它+1,来判断它的最低有效字节是一个字节还是两个字节。
这里为什么用113呢?因为它转化为二进制是这样的:
MOV AX,113 //把113存到AX里
0000 0001 0001 0011 //113转二进制
ADD AX,1 //往AX寄存器里+1
0000 0000 0000 0001 //1转二进制
0000 0001 0001 0100 //113+1二进制结果
这里如果判断的是两个字节,那么1的个数为奇数,PF标志位的值应为0,如果判断的是一个字节,那么
PF标志位的值应为1。
运行结果:
AF(6 bit)[Auxiliary Carry Flag]
如果算术操作在结果的第3位发生进位或者借位,则将该标志位置1,否则清零。
这个运算在BCD运算中常被使用。
这个不经常用,这里就不做过多介绍了,它涉及到BCD运算,感兴趣的可以去看一看。
ZF(6 bit)[Zero flag]
若运算的结果为零则将其置1,反之清零。
经常与TEST、CMP等指令一起使用。
例1:判断某个值是否为0
MOV EAX,100 //把100存到EAX
MOV ECX,100 //把100存到ECX
CMP EAX,ECX //EAX与ECX进行相减,但结果不会存到EAX中
注:CMP指令对标志位的影响同SUB指令,完成的操作与SUB指令类似,唯一的区别是不将OPRD1-OPRD2的结果送回OPRD1,而只是比较。
运行结果:
例2:判断两个值是否相等
TEST EAX,ECX //EAX和ECX进行按位的与运算,相同得0不同得1
注:TEST与AND指令的关系,有点类似于CMP与SUB指令之间的关系。
运算结果:
SF(7 bit) [Sing flag]
该标志被设置为有符号整形的最高有效位。
0表示运算的结果为负,1表示运算的结果为正。
常用作符号位
例:
MOV AL,0X7F
ADD AL,2
运行结果:
OF(11 bit)[Overflow flag]
溢出标志OF用于反应有符号数加减运算所得结果是否溢出。
可以这样理解:
如果是无符号数运算,是否溢出看CF位。
如果是有符号数运算,是否溢出看OF位。
这里要运算的数字,到底是有符号数还是无符号数,这就取决于你自己了。
若OF位为1则运算结果溢出,反之为0.
例1:
这里我们把运算数字当作无符号数
MOV AL.0X7F
ADD AL,2
运行结果:
例2:
还是刚才的指令,这里我们当作有符号数来看待
MOV AL.0X7F
ADD AL,2
运行结果:
同样的两个表达式,究竟是看CF位还是OF位,这要看你自己。
DF(10 bit)[Direction flag]
这个方向标志控制串指令(MOVS,CMPS,SCAS,LODS以及STOS)。设置DF标志使得串指令自动递减(从高地址向低地址处理字符串),清除该标志则使得串指令递增。
STO以及CLD指令分别用于设置以及清楚DF标志。
常用的JCC指令表
JCC指令 | 中文含义 | 标志符号位 |
---|---|---|
JE,JZ | 结果为零则跳转(相等时跳转) | ZF=1 |
JNZ,JNE | 结果不为零则跳转(不相等时跳转) | ZF=0 |
JS | 结果为负则跳转 | SF=1 |
JNS | 结果为非负则跳转 | SF=0 |
JP,JPE | 结果中1的个数为偶数则跳转 | PF=1 |
JNP,JPO | 结果中1的个数为奇数则跳转 | PF=0 |
JO | 结果溢出则跳转 | OF=1 |
JNO | 结果无溢出则跳转 | OF=0 |
JB,JNAE | 若小于则跳转(无符号数) | CF=1 |
JNB,JAE | 小于等于则跳转(无符号数) | CF=0 |
JBE,JNA | 小于等于则跳转(无符号数) | ZF=1 or CF=1 |
JNBE,JA | 大于则跳转(无符号数) | ZF=0 or CF=0 |
JL,JNGE | 小于则跳转(有符号数) | SF ≠ OF |
JNL,JGE | 大于等于则跳转(有符号数) | SF = OF |
JLE,JNG | 小于等于则跳转(有符号数) | ZF≠ OF or ZF=1 |
JNLE,JG | 大于则跳转(有符号数) | SF=0F and ZF=0 |
总结
- 只要是运算相关的指令,都会影响标志寄存器。
- 所有JCC指令都是根据标志寄存器来决定是否要修改EIP。
- 多加思考,勤加练习!