JCC指令
cc
代表 condition code(状态码)
Jcc不是单个指令,它只是描述了跳转之前检查条件代码的跳转助记符
例如JNE
,在跳转之前检查条件代码
典型的情况是进行比较(设置CC),然后使用跳转助记符之一
CMP EAX,0
JNE XXXXX
条件代码也可以用AND、OR、XOR、加法、减法(当然也可以是CMP)等指令来设置
JCC指令用于改变EIP(CPU要读取的指令地址)
JMP指令
JMP指令:修改EIP的值
JMP指令只影响了EIP,不影响堆栈和其它通用寄存器
JMP 寄存器/立即数 相当于 MOV EIP,寄存器/立即数
CALL指令
CALL指令和JMP指令都会修改EIP的值
但CALL指令会将返回地址(CALL指令的下一条指令地址)压入堆栈
因此也会引起esp的变化
RET指令
call调用跳转后执行完相关代码完要返回到call的下一条指令时使用ret指令
ret指令相当于pop eip
比较指令
CMP指令
指令格式:CMP R/M,R/M/IMM
CMP指令只改变标志寄存器的值
该指令是比较两个操作数,实际上,它相当于SUB指令,但是相减的结果并不保存到第一个操作数中
只是根据相减的结果来改变ZF零标志位的,当两个操作数相等的时候,零标志位置1
例:
MOV EAX,100
MOV EBX,200
CMP EAX,ECX
CMP AX,WORD PTR DS:[405000]
CMP AL,BYTE PTR DS:[405000]
CMP EAX,DWORD PTR DS:[405000]
TEST指令
指令格式:TEST R/M,R/M/IMM
该指令在一定程度上和CMP指令时类似的,两个数值进行与操作,结果不保存,但是会改变相应标志位
与的操作表项如下:
运算 |
结果 |
1 and 1 |
1 |
1 and 0 |
0 |
0 and 1 |
0 |
0 and 0 |
0 |
可以看到只要有任一操作数为0时,结果就为0
常见用法:用这个指令,可以确定某寄存器是否等于0
只有当eax=0时 eax and eax才会是0
所以
TEST EAX,EAX
观察ZF(零标志位)就可以判断EAX是否为0
JCC指令表
首先要明确一点,所有的判断跳转指令都是根据标志位来进行判断的
JCC指令也只影响EIP
指令 |
英文全称 |
含义 |
判断标志位 |
JE, JZ |
jump equal,jump zero |
结果为零则跳转(相等时跳转) |
ZF=1 |
JNE, JNZ |
jump not equal,jump not zero |
结果不为零则跳转(不相等时跳转) |
ZF=0 |
JS |
jump sign |
结果为负则跳转 |
SF=1 |
JNS |
jump not sign |
结果为非负则跳转 |
SF=0 |
JP, JPE |
jump parity,jump parity even |
结果中1的个数为偶数则跳转 |
PF=1 |
JNP, JPO |
jump not parity,jump parity odd |
结果中1的个数为偶数则跳转 |
PF=0 |
JO |
jump overflow |
结果溢出了则跳转 |
OF=1 |
JNO |
jump not overflow |
结果没有溢出则跳转 |
OF=0 |
JB, JNAE |
jump below,jump not above equal |
小于则跳转 (无符号数) |
CF=1 |
JNB, JAE |
jump not below,jump above equal |
大于等于则跳转 (无符号数) |
CF=0 |
JBE, JNA |
jump below equal,jump not above |
小于等于则跳转 (无符号数) |
CF=1 or ZF=1 |
JNBE, JA |
jump not below equal,jump above |
大于则跳转(无符号数) |
CF=0 and ZF=0 |
JL, JNGE |
jump less,jump not greater equal |
小于则跳转 (有符号数) |
SF≠ OF |
JNL, JGE |
jump not less,jump greater equal |
大于等于则跳转 (有符号数) |
SF=OF |
JLE, JNG |
jump less equal,jump not greater |
小于等于则跳转 (有符号数) |
ZF=1 or SF≠ OF |
JNLE, JG |
jump not less equal,jump greater |
大于则跳转(有符号数) |
ZF=0 and SF=OF |