函数调用约定
函数调用约定
函数调用约定,是指当一个函数被调用时,函数的参数会被传递给被调用的函数和返回值会被返回给调用函数。
函数的调用约定决定:
- 函数参数的压栈顺序
- 由调用者还是被调用者把参数弹出栈
- 以及产生函数修饰名的方法
函数调用约定的种类:
-
__cdecl
缺省调用方式,函数采用从右到左的压栈方式,调用方清理堆栈,注意可变参数
-
__stdcall
函数的参数自右向左通过栈传递,被调用方清理堆栈
-
__fastcall
通过寄存器来传送参数,被调用方清理堆栈
-
thiscall
用于C++成员函数,使用ecx存放this指针
-
naked call
裸函数,上面几种方式会产生保存一些寄存器的代码,这种不产生。naked call不是类型修饰符,必须和_declspec共同使用
-
__declspec(naked)
告诉编译器 不要对函数进行优化 函数的所有实现包括堆栈的平衡 参数的压栈 ebp的赋值 还原 都要自己来做
修饰名
修饰名(Decorationname):"C"或者"C++"函数在内部(编译和链接)通过修饰名识别
C编译时函数名修饰约定规则:
-
__stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个"@"符号和其参数的字节数。
格式为_functionname@number, 例如 :function(int a, int b),其修饰名为:_function@8
-
__cdecl调用约定仅在输出函数名前加上一个下划线前缀。
格式为:_functionname。
-
__fastcall调用约定在输出函数名前加上一个"@"符号,后面也是一个"@"符号和其参数的字节数。
格式为:@functionname@number。