你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

IA-32指令(一)——经典定长指令

2021/12/9 0:18:32

一. IA-32指令格式

1. 知识补充(JCC)

JCC意义标志位
JE、JZ结果为零则跳转(相等时跳转)ZF=1
JNE、JNZ结果不为零则跳转(不相等时跳转)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、JC小于则跳转 (无符号数)CF=1
JNB、JAE、JNC大于等于则跳转 (无符号数)CF=0
JBE、JNA小于等于则跳转 (无符号数)CF=1 or ZF=1
JBNE、JA大于则跳转(无符号数)CF=0 and ZF=0
JL、JNGE小于则跳转 (有符号数)SF≠OF
JNL、JGE大于等于则跳转 (有符号数)SF=OF
JLE、JNG小于等于则跳转 (有符号数)ZF=1 or SF≠OF
JNLE、JG大于则跳转(有符号数)ZF=0 and SF=OF

2. 指令格式

在这里插入图片描述

寄存器编号:

在这里插入图片描述

3. intel手册缩写表

详见Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2 APPENDIX A OPCODE MAP, KEY TO ABBREVIATIONS

(1) 寻址方法代码

缩写意义
E在opcode后面有一个字节的ModR/M, ModR/M制定了操作数的类型. 操作数是通用寄存器或者内存地址
FEFLAGS/RFLAGS Register.
GModR/M的reg字段选择的一个通用寄存器
I立即数, 该操作数的值被直接编码到了指令的后续字节中
J用来修改EIP的相对偏移量

(2) 操作数类型代码

缩写意义
b字节, 不管操作数大小属性
c字节或字,取决于操作数大小属性
d四字节, 不管操作数大小属性
v字、双字或四字(在64位模式下), 取决于操作数大小属性
w两个字节,不考虑操作数大小属性

二. 经典定长指令

1. 0x50-0x57

指令长度: 1字节

硬编码汇编
0x50PUSH EAX
0x51PUSH ECX
0x52PUSH EDX
0x53PUSH EBX
0x54PUSH ESP
0x55PUSH EBP
0x56PUSH ESI
0x57PUSH EDI

2. 0x58-0x5F

指令长度: 1字节

硬编码汇编
0x58POP EAX
0x59POP ECX
0x5APOP EDX
0x5BPOP EBX
0x5CPOP ESP
0x5DPOP EBP
0x5EPOP ESI
0x5FPOP EDI

3. 0x60-0x61

指令长度: 1字节

硬编码汇编
0x60PUSHAD
0x61PUSHFD

4. 0x40-0x47

指令长度: 1字节

硬编码汇编
0x40INC EAX
0x41INC ECX
0x42INC EDX
0x43INC EBX
0x44INC ESP
0x45INC EBP
0x46INC ESI
0x47INC EDI

5. 0x48-0x4F

指令长度: 1字节

硬编码汇编
0x48DEC EAX
0x49DEC ECX
0x4ADEC EDX
0x4BDEC EBX
0x4CDEC ESP
0x4DDEC EBP
0x4EDEC ESI
0x4FDEC EDI

6. 0xB0-0xB7

指令长度: 2字节

硬编码汇编
0xB0MOV AL, Ib
0xB1MOV CL, Ib
0xB2MOV DL, Ib
0xB3MOV BL, Ib
0xB4MOV AH, Ib
0xB5MOV CH, Ib
0xB6MOV DH, Ib
0xB7MOV BH, Ib

7. 0xB8-0xBF

指令长度: 5字节

硬编码汇编
0xB8MOV EAX, Id
0xB9MOV ECX, Id
0xBAMOV EDX, Id
0xBBMOV EBX, Id
0xBCMOV ESP, Id
0xBDMOV EBP, Id
0xBEMOV ESI, Id
0xBFMOV EDI, Id

8. 0x90-0x97

指令长度: 1字节

硬编码汇编
0x90NOP(XCHG EAX, EAX)
0x91XCHG EAX, ECX
0x92XCHG EAX, EDX
0x93XCHG EAX, EBX
0x94XCHG EAX, ESP
0x95XCHG EAX, EBP
0x96XCHG EAX, ESI
0x97XCHG EAX, EDI

Intel在设计的时候会对0号寄存器照顾,也就是0号寄存器会有单独的指令,对于XCHG EBX, EDX就没有一个字节的指令了

注意: XCHG ECX, EAX和XCHG EAX, ECX硬编码相同,其余同理,但是XCHG EBX, ECX和XCHG ECX, EBX硬编码不同

9. 0x70-0x7F

指令长度: 2字节

条件跳转,后跟一个字节立即数的偏移(有符号数)

jcc Jb

Jb = 要跳转的地址 - 下一条指令的地址 = 要跳转的地址 - (当前指令地址 + 当前指令长度)

如果条件成立,跳转到当前指令地址 + 当前指令长度 + Jb

最大向前跳0x7F,向后跳0x80

硬编码汇编
0x70JO
0x71JNO
0x72JB/JNAE/JC
0x73JNB/JAE/JNC
0x74JZ/JE
0x75JNZ/JNE
0x76JBE/JNA
0x77JNBE/JA
0x78JS
0x79JNS
0x7AJP/JPE
0x7BJNP/JPO
0x7CJL/JNGE
0x7DJNL/JGE
0x7EJLE/JNG
0x7FJNLE/JG

10. 0x0F 0x80 - 0x0F 0x8F

指令长度: 六个字节

条件跳转,后跟四个字节立即数的偏移(有符号数)

jcc Jd

Jd = 要跳转的地址 - 下一条指令的地址 = 要跳转的地址 - (当前指令地址 + 当前指令长度)

如果条件成立,跳转到当前指令地址 + 当前指令长度 + Jd

最大向前跳0x7FFFFFFF,向后跳0x80000000

硬编码汇编
0x0F 0x80JO
0x0F 0x81JNO
0x0F 0x82JB/JNAE/JC
0x0F 0x83JNB/JAE/JNC
0x0F 0x84JZ/JE
0x0F 0x85JNZ/JNE
0x0F 0x86JBE/JNA
0x0F 0x87JNBE/JA
0x0F 0x88JS
0x0F 0x89JNS
0x0F 0x8AJP/JPE
0x0F 0x8BJNP/JPO
0x0F 0x8CJL/JNGE
0x0F 0x8DJNL/JGE
0x0F 0x8EJLE/JNG
0x0F 0x8FJNLE/JG

11. 其他指令

(1) 0xE0

LOOPNE/LOOPNZ Jb

指令长度: 两个字节

ECX = ECX - 1

当ZF = 0 && ECX!=0 时跳转到当前指令地址 + 当前指令长度 + Jb

(2) 0xE1

LOOPE/LOOPZ Jb

指令长度: 两个字节

ECX = ECX - 1

当ZF = 1 && ECX != 0 时跳转到当前指令地址 + 当前指令长度 + Jb

(3) 0xE2

LOOP Jb

指令长度: 两个字节

ECX = ECX - 1

当 ECX!=0 时跳转到当前指令地址 + 当前指令长度 + Jb

(4) 0xE3

JrCXZ Jb (在32位模式中,rCX为ECX; 在64位模式中,rCX为RCX)

指令长度: 两个字节

当 ECX = 0 时跳转到当前指令地址 + 当前指令长度 + Jb

执行前后ECX不会自动改变,需要自己手动控制步长

(5) 0xE8

CALL Jd

指令长度: 五个字节

CALL指令的下一条指令地址入栈后,跳转到当前指令地址 + 当前指令长度 + Jd

(6) 0xE9

JMP Jd

指令长度: 五个字节

跳转到当前指令地址 + 当前指令长度 + Jd

(7) 0xEA

JMP Ap (Ap: 六字节长度的直接地址)

指令长度: 七个字节

JMP CS:Id 将imm48中的高2位赋值给CS,低4位直接赋值给EIP

EA 12345678 1B00  --->  jmp far 1B:78563412

(8) 0xEB

JMP Jb

指令长度: 两个字节

跳转到当前指令地址 + 当前指令长度 + Jb

(9) 0xC3

RET

指令长度: 一个字节

EIP出栈

(10) 0xC2

RET Iw

指令长度: 三个字节

EIP出栈后,ESP = ESP + Iw

(11) 0xCB

RETF (return far)

指令长度: 一个字节

长调用且跨段不提权时

pop eip
pop cs

(12) 0xCA

RETF Iw

指令长度: 三个字节s

长调用且跨段不提权时

pop eip
pop cs
ESP = ESP + Iw