vc编译器编译一个很简单的C程序
- C/C++ code
int main(void){ int i=1; return 0;}
编译的结果如下:
- Assembly code
; 1 : int main(void){ 00000 55 push ebp 00001 8b ec mov ebp, esp 00003 51 push ecx; 2 : int i=1; 00004 c7 45 fc 01 00 00 00 mov DWORD PTR _i$[ebp], 1; 3 : return 0; 0000b 33 c0 xor eax, eax; 4 : } 0000d 8b e5 mov esp, ebp 0000f 5d pop ebp 00010 c3 ret 0_main ENDP_TEXT ENDSEND
问题是,为什么要push ecx?而且程序结束的时候没有pop ecx的指令,意味着堆栈也没有被平衡啊?
这到底是怎么回事?
------解决方案--------------------------------------------------------
c语言中的函数对应的汇编码的头两句都是 push ebp mov ebp, esp
每个函数前的两句是为局部开辟内存空间,而局部变量不可覆盖,所以要保存局部变量的地址。BP入栈是保存BP的值,sp赋给BP是为了访问栈是用BP做偏移地址,如果有局部变量则后面紧跟一条 sub指令,如果没有则没有sub指令,
编译器不去考虑有没有局部变量,
没出出栈是应为,编译器有另一套机制保持程序的真确性,(出入栈会花很多时间的!)堆栈平衡 的话没必要用pop指令,直接改SP的值也可保证堆栈平衡的!
况且 0000f 5d pop ebp 有出栈啊!
建议去看一下 《汇编语言第二版》——王爽 研究试验3第3点!
------解决方案--------------------------------------------------------
不需要pop的原因是利用ebp还原esp