《C++黑客编程解密》05 - 汇编
x86汇编(32位)
CPU工作模式:
- 实模式:
早期Win9x DOS 所支持,可以直接访问硬件,直接对端口操作,对中断进行操作。现在cpu仍支持实模式,一是为了与早期cpu架构兼容,二是因为所有x86架构都是从实模式引导起来的。 - 保护模式:
每个进程间都是隔离的。现在处理器的主要工作模式。
x84 cpu中有4类寄存器
- 8个通用寄存器
EAX EBX ECX EDX 4个,每个都是32位,又可以当做16位和8位的使用。如EAX的低16位可作为AX,AX又可以按高低8位分为AH和AL。
指针寄存器可以按照32位和16位使用,但无法分为8位
通用寄存器的特殊用途
- EAX 在乘法和除法中被自动使用
- CPU 自动使用ECX作为循环计数器
- ESP 栈指针寄存器,始终指向栈顶
- ESI EDI 用于内存数据高速传送,源指针寄存器和目的指针寄存器
- EBP 高级语言用来应用参数和局部变量,通常被称为栈帧基址寄存器
- 6个段寄存器
- CS 代码段
- DS 数据段
- SS 堆栈段
- ES 附加段
- FS
- GS
- 1个标识寄存器
FLAGS(或 PSW) 此处介绍16位的标识寄存器,分为条件标识位和控制标识位。
条件标识位:
1 OF(Overflow Flag) 溢出时1,否则0
2 SZ(Sign Flag)符号标识,运算结果为负时为1,否则为0
3 ZF(Zero Flag)零标识,结果为0时为1,否则0
4 AF(Auxiliary carry Flag)辅助进位标识,记录运算时第3位(半字节)产生的进位,有进位为1
5 PF(Parity Flag)奇偶标识,结果操作数中1的个数为偶数时为1,否则为0
6 CF(Carry Flag)进位标识,产生进位时 1,否则0
控制寄存器:
1 DF(Direction Flag)方向标识,串处理指令中用于控制方向
2 IF(Interrupt Flag)中断标志
3 TF(Trap Flag)陷阱标志 - 1个指令寄存器
EIP 保存吓一跳指令的地址
数据传输指令
- mov 目的操作数, 源操作数 ;数据传送指令
- xchg 目标操作数,源操作数 ;交换两个操作数的数据
- push 操作数
把一个操作数送入堆栈。因为堆栈是由高地址向低地址延申,esp寄存器的值递减。在32位平台上每次减4。 - pop 操作数
把esp指向地址(栈顶)中的值送入寄存器或内存,然后esp地址加4。 - lea 目的操作,源操作数 ;装入有效地址,它的操作数就是地址而不是具体数据,这个lea与mov的区别
算术运算指令
- add
- sub
- adc 目的操作数,源操作数
类似add指令,区别在于相加后要再加上CF中值。 目的操作数 = 目的操作数 + 源操作数 + CF中值 - sbb
目的操作数 = 目的操作数 - 源操作数 - CF中值 - inc
加一 - dec
减一
操作内存时如果无法明确内存长度,要指出长度。
dword ptr
word ptr
byte ptr
分别指 4 2 1 个字节
位运算
- and
影响标识位 OF SF ZF PF CF - or
影响 OF SF ZF PF CF - not
- xor
影响 OF SF ZF PF CF - test
测试指令,测试目标操作数的单个位,与逻辑与类似,影响标识位,但不改变目的操作数内容
影响 OF SF ZF PF ZF
流程控制指令
- cmp
隐含执行减法,只影响标识位,不改变操作数
影响 OF SF ZF AF PF CF - jmp
无条件跳转 - jcc 条件跳转
- loop
循环控制指令,与 ecx 搭配,执行到 loop 语句时,先将 ecx 中的值减1,如果 ecx 大于0,则跳转到 loop 指令后的标号处。 - call
过程调用指令,将下一条指令地址压入堆栈,并将控制转移到目的地址
相当于执行了push eip
和jmp 目的地
两条指令 - ret
过程返回指令,相当于 pop eip 指令
eip 寄存器无法直接操作,只有通过流程控制指令改变eip寄存器
寻址方式
- 指令中给出数据
- 数据在寄存器中
- 数据在内存中
- 直接寻址
mov eax, [00402000h]
- 寄存器间接寻址
mov eax,[eax]
- 其他
- 直接寻址