关于函数调用约定的学习笔记
2013-08-02 22:48
453 查看
总体概述:
关于调用约定中,主要涉及的内容就是不同的调用约定对于函数调用栈平衡是由调用者维护栈平衡还是被调用者自己维护栈平衡、传入参数的方向从右到左还是从左到右通过栈传参还是通过寄存器传参、还有一个就是关于不同调用约定方式对于函数名的修饰方式。总体上了解这些就差不多了。
----------------------------------------------------------------------
调用者自己恢复栈平衡,用于可变参函数,调用约定为__cdecl,汇编代码表现
push 参数
call 函数
add esp,4
被调用者自己恢复栈平衡__stdcall
push 参数
call 函数
采用寄存器传参__fastcall
mov edx,参数
mov ecx,参数
call 函数
以上各种调用约定对应的编译器选项 /Gz (stdcall)、/Gr (fastcall)、/Gd (cdecl)
说明:在MSDN帮助文档中可以搜关键字__cdcel
----------------------------------------------------------------------
关于使用不同调用约定的C函数名修饰:
C 函数的修饰形式取决于其声明中使用的调用约定,如下所示。
调用约定 修饰
__cdecl(默认值) 前导下划线 (_)
__stdcall 前导下划线 (_) 和结尾 at 符 (@),后面跟表示参数列表中的字节数的数字
__fastcall 与 __stdcall 相同,但前置符不是下划线,而是 @ 符
实例分析:(自己动手实践验证VS2010)
函数原型: 修饰后的名称:
int __fastcall fun3(int a, int b); @fun3@8
int __stdcall fun2(int a, int b); _fun2@8
int __cdecl fun1(int a, int b); _fun1
------------------------C++ 修饰名的格式----------------------------------------------
C++ 函数的修饰名包含下列信息:
函数名。
函数所属的类(如果函数是成员函数)。这可能包括封装函数的类的类,等等。
函数所属的命名空间(如果函数是某个命名空间的组成部分)。
函数的参数类型。
调用约定。
函数的返回类型。
函数名和类名在修饰名中以代码形式存在。修饰名的其余部分是仅对编译器和链接器具有内部意义的代码。下面是未修饰的和修饰的 C++ 名称的示例。
未修饰名 修饰名
int a(char){int i=3;return i;}; ?a@@YAHD@Z
void __stdcall b::c(float){}; ?c@b@@AAGXM@Z
------------Argument Passing and Naming Conventions---------------------------------
Microsoft Specific
All arguments are widened to 32 bits when they are passed. Return values are also widened to 32 bits and returned in the EAX register, except for 8-byte structures, which are returned in the EDX:EAX register pair. Larger structures are returned in the EAX register
as pointers to hidden return structures. Parameters are pushed onto the stack from right to left. Structures that are not PODs will not be returned in registers.
The compiler generates prolog and epilog code to save and restore the ESI, EDI, EBX, and EBP registers, if they are used in the function.
Note:
When a struct, union, or class is returned from a function by value, all definitions of the type need to be the same, else the program may fail at runtime.
For information on how to define your own function prolog and epilog code, see (Naked Function Calls).
The following calling conventions are supported by the Visual C/C++ compiler.
Keyword Stack cleanupParameter passing
__cdecl CallerPushes parameters on the stack, in reverse order (right to left)
__clrcall n/a
Load parameters onto CLR expression stack in order (left to right).
__stdcall CalleePushes parameters on the stack, in reverse order (right to left)
__fastcall CalleeStored in registers, then pushed on stack
__thiscall CalleePushed on stack; this pointer stored in ECX
最后补充一点就是关于调用约定在IPF处理器和X64处理器下的一些说明,以下引用自MSDN帮助手册中的原话:
On Itanium Processor Family (IPF) and x64 processors, __cdecl is accepted and ignored by the compiler; on IPF, by convention, parameters are passed in register.
On Itanium Processor Family (IPF) and x64 processors, __stdcall is accepted and ignored by the compiler; on IPF, by convention, parameters are passed in register.
On Itanium Processor Family (IPF) and AMD64 machines, __fastcall is accepted and ignored by the compiler; on an IPF chip, by convention, parameters are passed in register.
主要说的就是在这两种处理直接采用寄存器传参方式。
相关文章推荐
- IDA学习笔记 函数调用约定
- 韩顺平_轻松搞定网页设计(html+css+javascript)_第26讲_js函数调用过程内存分析_js函数细节_学习笔记_源代码图解_PPT文档整理
- JavaScript学习笔记第一天——定义函数以及参数调用
- C++ Primer 学习笔记11 函数(函数调用、引用形参、非引用形参)
- nginx 源码学习笔记(十九)—— nginx启动过程函数调用图
- 编译原理之学习 lua 1.1 笔记 (二) 函数调用与局部变量
- C/C++中关于地址、指针和引用变量的学习笔记(四) : 函数
- 汇编学习第五课之函数调用约定:cdecl,stdcall,fastcall
- 【C#学习笔记】函数调用
- 关于一个工程中多个文件的相互调用的学习笔记(C语言)
- 关于SQL Server 2005的学习笔记―分析函数
- C++学习笔记:重载 函数调用符()
- c++学习笔记 内存四区 函数调用模型 指针强化
- 函数调用约定学习(一)
- nginx 源码学习笔记(十九)—— nginx启动过程函数调用图
- javascript语言精粹学习笔记之函数的四种this调用模式
- C++ Primer 学习笔记_62_满载操作符与转换 -调用操作符和函数对象
- 通过VC学习反汇编——函数调用:调用约定
- 【学习笔记】自定义关于wchar_t*的相关函数
- python学习笔记之调用eval函数出现invalid syntax错误问题