设为首页 加入收藏

TOP

VC++中的函数调用惯例(二)
2013-04-10 11:37:41 来源: 作者: 【 】 浏览:332
Tags:函数 调用 惯例

 

  48: if ( m= s )

  004011B3 mov eax,dword ptr [ebp+8]

  004011B6 mov ecx,dword ptr [eax]

  004011B8 cmp ecx,dword ptr [ebp-4]

  004011BB jl Input+0AFh (004011bf)

  57: break;

  004011BD jmp Input+0C1h (004011d1)

  58: else

  59: printf(" m < n*(n+1)/2,Please input again!\n");

  004011BF push offset string " m < n*(n+1)/2,Please input agai"... (00426060)

  004011C4 call printf (00401530)

  004011C9 add esp,4

  60: }

  004011CC jmp Input+18h (00401128)

  61:

  62: }

  004011D1 pop edi

  004011D2 pop esi

  004011D3 pop ebx

  004011D4 add esp,48h

  004011D7 cmp ebp,esp

  004011D9 call __chkesp (004015b0)

  004011DE mov esp,ebp

  004011E0 pop ebp

  004011E1 ret 8

  -

  最后,我们看到在函数末尾部分,有ret 8,明显是恢复堆栈, 由于在32位C++(www.cppentry.com)中,变量地址为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反汇编代码。

      

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇VC++实现视频捕获编程 下一篇在VC中实现全屏窗口程序

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: