推荐: blog.csdn.net/aquester https://github.com/eyjian https://www.cnblogs.com/aquester http://blog.chinaunix.net/uid/20682147.html
全部博文(595)
分类: C/C++
2019-01-29 11:21:27
在main函数中,return和exit经常混用,两者的一个区别:return会执行statck unwinding,而exit不会。如果触发了信号,exit也同样不会做stack unwinding,除此之外异常如果没有相应的catch,也同样不会有栈展开(stack unwinding)。
原因是C++编译器只会在遇到“}”或“return”时,才会安插栈展开代码,对于exit等则没这回事。
#include
#include
#include
class X { public: X(int m): _m(m) { printf("X::ctor:%d\n", m); } ~X() { printf("X::dtor:%d\n", _m); }
private: int _m; };
int main() { X x(1); #if USE_EXIT exit(0); #if USE_RAISE raise(SIGSEGV); #else return 0; #endif } |
以上述代码为例,通过汇编,可很容易看出这两者的区别:
1) return代码
int main() { X x(1); return(0); } |
反汇编main函数,可以看到有调用~X:
0x08048474 <main+0>: lea 0x4(%esp),%ecx
0x08048478
0x0804847b
0x0804847e
0x0804847f
0x08048481
0x08048482
0x08048483
0x08048486
0x0804848e
0x08048491
0x08048494
0x08048499
0x0804849e
0x080484a1
0x080484a4
0x080484a9
0x080484ab
0x080484ae
0x080484af
0x080484b0
0x080484b1
0x080484b4 |
2) exit代码
int main() { X x(1); exit(0); } |
反汇编main函数,可以看到没有调用~X:
0x080484a4 <main+0>: lea 0x4(%esp),%ecx
0x080484a8
0x080484ab
0x080484ae
0x080484af
0x080484b1
0x080484b2
0x080484b5
0x080484bd
0x080484c0
0x080484c3
0x080484c8
0x080484cf |
附:汇编指令
call指令 |
分两步: 1) 将当前的IP或CS和IP压入栈中 2) 转移(能实现短转移,它的书写格式同jmp指令) |
ret指令 |
相当于pop IP |
retf指令 |
相当于: 1) pop IP 2) pop CS |
lea指令 |
把操作数OPRD的偏移地址传送到寄存器REG,语法:LEA REG, OPRD |