思考
- 什么是执行流?
- 执行流的基本结构?
执行流
什么是执行流
- 使用Java、C++写程序,基本单位是类的方法;
- 使用C语言写程序,基本单位是函数;
- 使用汇编写程序,基本单位就称为执行流(CPU执行引擎执行程序也称为执行流);
执行流的基本结构
// cpp代码 int print() { int a = 10; return a; } int main() { print(); return 0; }
;print()函数的堆栈对应的汇编代码 00661E40 push ebp 00661E41 mov ebp,esp ;开辟新的栈帧 一个函数一个栈帧 00661E43 sub esp,0CCh ---------------------------------------------------------------------- 00661E49 push ebx 00661E4A push esi ;保存现场 00661E4B push edi ---------------------------------------------------------------------- ;初始化栈内存 00661E52 mov ecx,33h; ; 设置循环计数器为51(0x33为十六进制,对应十进制的51) 00661E57 mov eax,0CCCCCCCCh ;eax寄存器设置为0xCCCCCCCC 0xcc int 3 调试断点 烫烫 00661E5C rep stos dword ptr es:[edi] ;在堆栈中填充0xCCCCCCCC,总共填充51次(由ecx决定) ---------------------------------------------------------------------- 9: int a = 10; 00661E68 mov dword ptr [ebp-8],0Ah 10: return a; ;业务逻辑 00661E6F mov eax,dword ptr [ebp-8] 11: } ---------------------------------------------------------------------- 00661E72 pop edi 00661E73 pop esi ;恢复现场 00661E74 pop ebx ---------------------------------------------------------------------- 00661E82 mov esp,ebp 00661E84 pop ebp ;恢复栈帧 局部变量 ---------------------------------------------------------------------- 00661E85 ret
执行流结构图:
深入理解栈指令本质
1. push 2. pop 3. jmp 4. call 5. ret
push
push 10
指令等于两条基本指令的组合:
sub esp, 4
mov dword ptr [esp], 10
pop
pop eax
等于两条基本指令的组合:
mov eax, [esp]
add esp, 4
注意点:
mov eax, esp·
与mov eax, [esp]
区别
mov eax, esp
:
- 这条指令将寄存器
esp
(堆栈指针寄存器)的值复制到eax
寄存器中。 - 换句话说,如果
esp
包含值0x12345678
,那么执行此指令后eax
也将包含值0x12345678
。
mov eax, [esp]
:
- 这条指令读取存储在由
esp
寄存器指向的内存地址的值,并将其放入eax
寄存器中。 - 如果
esp
包含值0x12345678
,那么这条指令会从内存地址0x12345678
中取出4个字节(假设这是32位x86代码)的数据,并将这些数据放入eax
寄存器中。
总结:
mov eax, esp
将esp
的值复制到eax
。mov eax, [esp]
从esp
指向的内存地址读取数据,并将这些数据放入eax
。
call
call printf
指令等于两条基本指令的组合:
call
指令的下一行指令地址压入栈push return address
;- 跳到函数地址处
jmp print
;
ret
ret
等于两条基本指令的组合:
pop eip
jmp eip
画堆栈图与构建执行流
- 先看汇编代码
//mian函数的堆栈对应汇编代码 13: int main() 14: { 00EE17B0 push ebp 00EE17B1 mov ebp,esp 00EE17B3 sub esp,0CCh ---------------------------------------------------------------------- 00EE17B9 push ebx 00EE17BA push esi 00EE17BB push edi ---------------------------------------------------------------------- 00EE17C2 mov ecx,33h 00EE17C7 mov eax,0xCCCCCCCCh 00EE17CC rep stos dword ptr es:[edi] ---------------------------------------------------------------------- 15: int a = 10; 00EE17D8 mov dword ptr [ebp-8],0Ah 16: print(); 00EE17DF call 00EE137A 17: 18: return 0; 00EE17E4 xor eax,eax 19: ---------------------------------------------------------------------- 00EE17E6 pop edi 00EE17E7 pop esi 00EE17E8 pop ebx ---------------------------------------------------------------------- 00EE17E9 add esp,0CCh 00EE17EF cmp ebp,esp 00EE17F1 call 00EE1217 00EE17F6 mov esp,ebp 00EE17F8 pop ebp ---------------------------------------------------------------------- 00EE17F9 ret
- 根据相应的汇编逻辑绘制执行流