函数调用约束

2021-09-17  本文已影响0人  突然的自我_39c1

什么是调用约定

函数的调用约定,顾名思义就是对函数调用的一个约束和规定(规范),描述了函数参数是怎么传递和由谁清除堆栈的。

函数组成:返回值类型 调用约定 函数名(参数列表...)

void __cdecl function(int a,int b);
void __stdcall function(int a,int b);

上面的__cdecl和__stdcall就是调用约定,其中__cdecl是C和C++默认的调用约定;译器默认会为我们使用__cdecl调用约定;常见的调用约定有__cdecl、__stdcall、fastcall,应用最广泛的是__cdecl和__stdcall,下面我们会详细进行讲述。。还有一些不常见的,如 __pascal、__thiscall、__vectorcall。

声明和定义处调用约定必须要相同

在VC++中,调用约定是函数类型的一部分,因此函数的声明和定义处调用约定要相同,不能只在声明处有调用约定,而定义处没有或与声明不同。

int __cdecl function(int a,int b);
int __cdecl function(int a,int b)
{
      return a+b;
}

函数的调用过程

要深入理解函数调用约定,你须要了解函数的调用过程和调用细节
假设函数A调用函数B,我们称A函数为”调用者”,B函数为“被调用者”。如下面的代码

int B(int a,int b)
{
    return a+b;
}
void A()
{
    std::cout()<<B(5,6)<<std::endl;
}

函数调用过程可以这么描述:

move %ebp ,%esp
pop  %ebp

__cdecl的特点

__cdecl 是 C Declaration 的缩写,表示 C 和 C++ 默认的函数调用约定。是C/C++和MFCX的默认调用约定;

从代码和程序调试的层面考虑,参数的压栈顺序和栈的清理我们都不用太观注,因为这是编译器的决定的,我们改变不了。但第三点却常常困扰我们,因为如果不弄清楚这点,在多个库之间(如dll、lib、exe)相互调用、依赖时常常出出现莫名其妙的错误。这个我在后面章节会进行详细介绍。

__stdcall的特点

__stdcall是Standard Call的缩写,是C++的标准调用方式,当然这是微软定义的标准,__stdcall通常用于Win32 API中(可查看WINAPI的定义)。

__fastcall的特点

__fastcall调用的主要特点就是快,因为它是通过寄存器来传送参数的。

__thiscall的特点

__thiscall是C++类成员函数缺省的调用约定,但它没有显示的声明形式。。因为在C++类中,成员函数调用还有一个this指针参数,因此必须特殊处理,thiscall调用约定的特点:

上一篇 下一篇

猜你喜欢

热点阅读