调用约定__cdecl和__stdcall
2014-10-27 11:11
246 查看
首先,__cdecl,c declaration,C风格声明。或者 c default calling(笔者瞎编的)。(那么问题来了,为什么PASCAL风格被称为std?)
调用约定的内容包括三点:参数出入栈顺序,弹栈工作由谁做,以及产生函数名的方式(renaming?)
1.
在参数入栈顺序上,__cdecl和__stdcall没有区别都是从右往左;
2.
__cdecl既然是c/c++默认,让我们回忆下下stl中的printf这样的变长参数函数,只有调用者才知道实参的情况,因此由调用者去负责恢复栈,大概是比较恰当的。
那么结论来了,__cdecl,指定了由调用者负责弹栈。
接着往下……
调用者负责弹栈,意味着,在最终的可执行代码中,所有调用被指定为__cdecl的方法的地方都会相对__stdcall多生成一段清理栈的代码。
换句话说,如果windows API作为一套已存在的系统/二进制码/或者其他什么,当它在调用应用程序提供的函数的时候,已经没办法知道程序员提供的方法(CALLBACK/WINAPI)要如何清理栈,
更不可能有机会将处理栈的代码新增到这套已经存在的“系统/二进制码/或者其他什么”中,因此必须由函数提供方自行处理栈。
这也就是CALLBACK/WINAPI为什么是__stdcall的原因。
3.
略。
调用约定的内容包括三点:参数出入栈顺序,弹栈工作由谁做,以及产生函数名的方式(renaming?)
1.
在参数入栈顺序上,__cdecl和__stdcall没有区别都是从右往左;
2.
__cdecl既然是c/c++默认,让我们回忆下下stl中的printf这样的变长参数函数,只有调用者才知道实参的情况,因此由调用者去负责恢复栈,大概是比较恰当的。
那么结论来了,__cdecl,指定了由调用者负责弹栈。
接着往下……
调用者负责弹栈,意味着,在最终的可执行代码中,所有调用被指定为__cdecl的方法的地方都会相对__stdcall多生成一段清理栈的代码。
换句话说,如果windows API作为一套已存在的系统/二进制码/或者其他什么,当它在调用应用程序提供的函数的时候,已经没办法知道程序员提供的方法(CALLBACK/WINAPI)要如何清理栈,
更不可能有机会将处理栈的代码新增到这套已经存在的“系统/二进制码/或者其他什么”中,因此必须由函数提供方自行处理栈。
这也就是CALLBACK/WINAPI为什么是__stdcall的原因。
3.
略。
相关文章推荐
- cdecl和stdcall调用约定的汇编代码对比
- cdecl、stdcall、fastcall函数调用约定区别
- cdecl、stdcall、fastcall函数调用约定区别
- 函数的调用约定 __stdcall __cdecl __fastcall
- cdecl、stdcall、fastcall函数调用约定区别
- __stdcall和__cdecl调用约定及名称改编约定
- 带你玩转Visual Studio——调用约定__cdecl、__stdcall和__fastcall
- 论调用约定__stdcall,__cdecl,__fastcall,thiscall,naked call
- 调用约定(Calling convention)详解(__stdcall,__cdecl,__fastcall)
- cdecl和stdcall调用约定的汇编代码对比
- cdecl、stdcall、fastcall函数调用约定区别
- __cdecl __fastcall与 __stdcall 调用约定
- 再议:__cdecl与__stdcall 调用约定在动态链接库调用中不同的表现
- cdecl, stdcall, pascal,fastcall 都有什么区别,具体是什么调用约定?
- __cdecl __stdcall各种调用约定详解
- cdecl, stdcall, pascal,fastcall 都有什么区别,具体是什么调用约定?
- __stdcall, __cdecl, __fastcall, __declspec几种调用约定及区别
- 函数命名规则及调用约定:__stdcall,__cdecl,__fastcall,thiscall,naked call
- 函数调用约定,_cdecl,_stdcall
- cdecl、stdcall、fastcall函数调用约定区别