VC++中的函数调用惯例
2010-08-15 20:47:34 来源:WEB开发网核心提示:最后,我们看到在函数末尾部分,VC++中的函数调用惯例(3),有ret 8,明显是恢复堆栈,然后api函数自己恢复堆栈,如:push edxpush edipush eaxpush ebxcall getdlgitemtexta你可以想一下, 由于在32位C++中,变量地址为4个字节(int也为4个字节)
最后,我们看到在函数末尾部分,有ret 8,明显是恢复堆栈, 由于在32位C++中,变量地址为4个字节(int也为4个字节),所以弹栈两个地址即8 个字节。
由此可以看出:在主调用函数中负责压栈,在被调用函数中负责 恢复堆栈。因此不能实现变参函数,因为被调函数不能事先知道弹栈数量,但在 主调函数中是可以做到的,因为参数数量由主调函数确定。
下面再看一下 ,ebp-8和ebp-4这两个地址实际存储的是什么值,ebp-8地址存储的是n 的值, ebp -4存储的是m的值。说明也是从右到左压栈,进行参数传递。
总结:在 主调用函数中负责压栈,在被调用函数中负责弹出堆栈中的参数,并且负责恢复 堆栈。因此不能实现变参函数,参数传递是从右到左。另外,命名修饰方法是在 函数前加一个下划线(_),在函数名后有符号(@),在@后面紧跟参数列表中的参数 所占字节数(10进制),如:void Input(int &m,int &n),被修饰成: _Input@8
对于大多数api函数以及窗口消息处理函数皆用 CALLBACK ,所以 调用前,主调函数会先压栈,然后api函数自己恢复堆栈。
如:
push edx
push edi
push eax
push ebx
call getdlgitemtexta
你可以想一下,这几个寄存器中存的都 是什么?
参考:msdn
例子为在VC6.0下debug模式下的Win32 Console反汇编代码。
更多精彩
赞助商链接