汇编
一、指令
1 mov
可以立即数到内存,寄存器到内存。内存到寄存器
1.1 mov指令操作的四种形式
- [立即数]
- [reg] reg代表寄存器 可以是8个通用寄存器中的任意一个
- [reg+立即数]
- [reg+reg*{1,2,4,8}]
1.2 指令格式
- MOV r/m8,r8 r通用寄存器
- MOV r/m16,r16 m代表内存
- MOV r/m32,r32 r8代表8位通用寄存器
- MOV r8,r/m8 m8代表8为内存
- MOV r16,r/m16 imm8代表8位立即数
- MOV r32,r/m32
- MOV r8,imm8
- MOV r16,imm16
- MOV r32,imm32
2 movs
移动数据 内存-内存 (EDI-ESI)
MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 简写为:MOVSB
MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI] 简写为:MOVSW
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 简写为:MOVSD
💡 默认DF位是0时,当完成movs操作后ESI和EDI的值会加byte,word,dword{1,2,4}
3 stos
将AI/AX/EAX的值存储到[EDI]指定的内存单元
STOS BYTE PRT ES:[EDI] 简写为STOSB
STOS WORD PRT ES:[EDI] 简写为STOSW
STOS DWORD PRT ES:[EDI] 简写为STOSD
💡 默认DF位是0时,当完成stos操作后EDI的值会加byte,word,dword{1,2,4}
4 rep
按计数寄存器ECX中指定的次数重复执行字符串指令
1 | MOV ECX,10 |
5 add
5.1 指令格式
- ADD r/m8,imm8
- ADD r/m16,imm16
- ADD r/m32,imm32
- ADD r/m16,imm8
- ADD r/m32,imm8
- ADD r/m8,r8
- ADD r/m16,r16
- ADD r/m32,r32
- ADD r8,,r/m8
- ADD r16,r/m16
- ADD r32,r/m32
6 sub
6.1 指令格式
- SUB r/m8,imm8
- SUB r/m16,imm16
- SUB r/m32,imm32
- SUB r/m16,imm8
- SUB r/m32,imm8
- SUB r/m8,r8
- SUB r/m16,r16
- SUB r/m32,r32
- SUB r8,,r/m8
- SUB r16,r/m16
- SUB r32,r/m32
7 and
7.1 指令格式
- AND r/m8,imm8
- AND r/m16,imm16
- AND r/m32,imm32
- AND r/m16,imm8
- AND r/m32,imm8
- AND r/m8,r8
- AND r/m16,r16
- AND r/m32,r32
- AND r8,r/m8
- AND r16,r/m16
- AND r32,r/m32
8 or
8.1 指令格式
- OR r/m8,imm8
- OR r/m16,imm16
- OR r/m32,imm32
- OR r/m16,imm8
- OR r/m32,imm8
- OR r/m8,r8
- OR r/m16,r16
- OR r/m32,r32
- OR r8,r/m8
- OR r16,r/m16
- OR r32,r/m32
9 not
9.1 功能
进行取反操作
9.2 指令格式
- NOT r32
- NOT r16
- NOT m16
- NOT m32
10 xor
10.1 指令格式
- XOR r/m8,imm8
- XOR r/m16,imm16
- XOR r/m32,imm32
- XOR r/m16,imm8
- XOR r/m32,imm8
- XOR r/m8,r8
- XOR r/m16,r16
- XOR r/m32,r32
- XOR r8,r/m8
- XOR r16,r/m16
- XOR r32,r/m32
11 push
11.1 功能
- 向堆栈中压入数据
- 然后修改栈顶指针ESP寄存器地址,看数据类型byte,word,dword分别对应-1,-2,-4
11.2 指令格式
- PUSH r32
- PUSH r16
- PUSH m16
- PUSH m32
- PUSH imm8/imm16/imm32
- PUSHAD(把8个通用寄存器的值存入堆栈,其中D是DWORD)
- PUSHFD (把32位的eflags寄存器压入栈中,其中D是DWORD)
11.3 其他方式实现该功能
12 pop
12.1 功能
- 将栈顶数据存储到寄存器/内存
- 修改栈顶指针ESP寄存器地址,看数据类型byte,word,dword分别对应+1,+2,+4
12.2 指令格式
- POP r16
- POP r32
- POP m16
- POP m32
- POPAD (把存入堆栈的8个寄存器值弹出,恢复8个寄存器的值)
- POPFD (把存入堆栈的32位eflags值弹出,恢复eflags值)
12.3 其他方式实现该功能
13 jmp
13.1 功能
- 修改寄存器EIP的值
13.2 指令格式
- JMP 寄存器/立即数/内存
14 call
14.1 功能
- PUSH当前call指令的下一行地址进入堆栈
- 往EIP内存入立即数/寄存器/内存 简写:jmp 立即数/寄存器/内存
💡 与JMP唯一的区别:在堆栈中存储call指令下一行内存地址
14.2 指令格式
- CALL 立即数/寄存器/内存
15 ret
15.1 功能
- 将当前栈顶数据值存入EIP ADD ESP,4
- 然后当前栈顶指针+4,赋值给ESP MOV EIP,[ESP-4]
15.2 指令格式
- RET
16 CMP
16.1 功能
该指令是比较两个操作数。
实际上,它相当于SUB指令,但是相减的记过并不保存到第一个操作数中。
只是根据相减的结果来改变零标志位的,当两个操作数相等的时候,零标志位置1。
16.2 指令格式
- CMP R/M,R/M/IMM
17 TEST
17.1 功能
TEST指令相当于AND指令,只不过与的结果并不保存到第一个操作数中。
该指令在一定程序上和CMP指令时类似的,两个数值进行AND操作,结果不保存,但是会改变相应标志位.
17.2 指令格式
TEST r/m,r/m/imm
18 ADC
18.1 功能
带进位加法,两边不能同时为内存 宽度要一样
18.2 指令格式
- ADC r/m,r/m/imm
19 SBB
19.1 功能
带借位减法,两边不能同时为内存 宽度要一样
19.2 指令格式
- SBB r/m,r/m
20 XCHG
20.1 功能
交换数据,两边不能同时为内存 宽度要一样
20.2 指令格式
- XCHG r/m,r/m
21 算术位移指令
21.1 SAL(算术左移)
SAR Reg/Mem, CL/Imm
21.2 SAR(算术右移)
SAR Reg/Mem, CL/Imm
注意:算术右移时候补最高位符号位,是1补1,是0补0
22 逻辑移位指令
注意:不管是左移还是右移都是补0
22.1 SHL(逻辑左移)
SHL Reg/Mem, CL/Imm
22.2 SHR(逻辑右移)
SHR Reg/Mem, CL/Imm
23 循环移位指令
23.1 ROL(循环左移)
ROL r/m, i8
最低位是1则补1,最低位是0则补0
23.2 ROR(循环右移)
ROR r/m, CL
最高位是1则补1,最高位是0则补0
24 带进位的循环移位指令
CF位是1则补1,反之则补0
24.1 RCL(带进位循环左移)
RCL r/m, i8
24.2 RCR(带进位循环右移)
RCR r/m, CL
二、存储模式
大端模式:数据高位在低位,数据低位在高位
小端模式:数据高位在高位,数据低位在低位
三 JCC
1 标志寄存器 EFLAGS
2 CF(bit 0)[Carry flag]
2.1 功能
若算术操作产生的结果在最高有效位发生进位或者借位则将其置1,反之清零。这个标志通常用来只是无符号整型运算的溢出状态。
👉 有符号运算看O位,无符号运算看C位
2.2 例子
3 PF (bit 2)[parity flag]
3.1 功能
如果结果的最低有效字节包含偶数个1位,则该位置1,否则清零。
利用PF课进行奇偶校验检查:
需要传输“11001110”,数据中含有5个“1”,所以其奇校验位为“0”,同时把“110011100”数据传输给接收方,接收方收到数据时后再一次计算奇偶性,“110011100”中仍然含有5个“1”,所以接收方计算出的奇校验位还是“0”,与发送方一致,表示在此次传输过程中未发生错误
4 AF(bit 4)[Auxiliary carry flag]
4.1 功能
- 在字操作时,发生低字节向高字节进位或借位时;
- 在字节操作时,发生低四位向高四位进位或借位时。
辅助进位标志AF的值被置为1,否则其值为0:
5 ZF(bit 6)[zero flag]
5.1 功能
零标志ZF用来反映运算结果是否为0。
若结果为0,则将其置1,反之清零
经常与CMP或者TEST等指令一起使用
6 SF(bit 7)[Sign flag]
6.1 功能
该标志被设置为有符号整型的最高有效位
0指示结果为正,反之则为负
7 OF(bit 11)[OverFlow flag]
7.1 功能
一处标志OF用于反映有符号数加减运算所得结果是否溢出。
如果是无符号数运算,是否溢出看CF位。
如果是有符号数运算,是否溢出看OF位。
8 DF(bit 10)[Oirection flag]
8.1 功能
这个方向标志控制串指令(MOVS,CMPS,SCAS,LODS以及STOS)设置DF标志是的串指令自动递减(从高地址向低地址方向处理字符串),清楚该标志则使得指令自动递增
STD以及CLD指令分别用于设置以及清楚DF标志
9 JCC指令
Index | JCC指令 | 说明 | EFLAGS |
---|---|---|---|
1 | JE ,JZ | 结果为零则跳转(相等时跳转) | ZF=1 |
2 | JNE,JNZ | 结果不为零则跳转(不相等时跳转) | ZF=0 |
3 | JS | 结果为负则跳转 | SF=1 |
4 | JNS | 结果为非负则跳转 | SF=0 |
5 | JP,JPE | 结果中1的个数为偶数则跳转 | PF=1 |
6 | JNP,JPO | 结果中1的个数为偶数则跳转 | PF=0 |
7 | JO | 结果溢出了则跳转 | OF=1 |
8 | JNO | 结果没有溢出则跳转 | OF=0 |
9 | JB,JNAE | 小于则跳转 (无符号数) | CF=1 |
10 | JNB,JAE | 大于等于则跳转 (无符号数) | CF=0 |
11 | JBE,JNA | 小于等于则跳转 (无符号数) | CF=1 or ZF=1 |
12 | JNBE,JA | 大于则跳转(无符号数) | CF=0 and ZF=0 |
13 | JL,JNGE | 小于则跳转 (有符号数) | SF≠ OF |
14 | JNL,JGE | 大于等于则跳转 (有符号数) | SF=OF |
15 | JLE,JNG | 小于等于则跳转 (有符号数) | ZF=1 or SF≠ OF |
16 | JNLE,JG | 大于则跳转(有符号数) | ZF=0 and SF=OF |
👉 在任何运算之前得先确定时有符号运算还是无符号运算