0x01 前言
在写C/C++程序的时候我们都知道函数的调用,但可能没有多少人关注其底层的原理,作为一名合格的开发人员,对所使用的开发语言应当有一定的原理了解,本文将简单介绍C/C++中的三种函数调用约定,这也是在面试的时候经常被问到的知识点。
0x02 __cdecl约定
__cdecl函数调用约定是我们最长见的一种约定,我们平时在写程序的时候默认会使用该种约定,其特点如下:
- 参数从右向左依次传递,存放在堆栈中。
- 堆栈平衡由调用函数来维护。
- C语言编译时的函数命名规则为下划线加名称:__functionName
堆栈平衡是为了维护函数调用前后堆栈的状态来进行的一系列操作,具体解释请自行百度。
0x03 __stdcall约定
__stdcall约定是我们在写WinAPI的时候经常用的约定,很多windows下面的API都是该种调用约定,其特点如下:
- 参数从右向左依次传递,存放在堆栈中。
- 堆栈平衡由被调用函数来维护
- C语言编译时的函数命名规则为下划线加名称加@加参数字节大小:__functionName@len
本约定在写WinAPI的时候经常用到,和_cdecl的却别在于堆栈平衡由函数自身进行维护。
0x04 __fastcall约定
__fastcall约定从名称上可以看出是速度快,因为其参数是可以放在寄存器中传递的,通常需要在要求高效率的函数中使用此约定,其特点如下:
- 最右侧两个参数由ecx和edx两个寄存器来传递,剩余参数从右往左依次存放在堆栈中。
- 堆栈平衡由被调用函数来维护
- C语言编译时的函数命名规则为@加函数名加@加参数大小:@functionName@len
该约定是高效率的调用约定,和另外两种约定最大的区别就是参数的传递方式,利用了寄存器来快速的传递。
0x05 关于C++编译时的函数名规则
上面介绍三种约定特点的时候都提到的C语言编译时的函数名的命名规则,C++和C语言的命名规则是不同的,C++要比C语言复杂的多,可能需要一整篇文章来介绍,这里简单提一下。
C++中编译时函数命名不分约定全部以@开头,然后加上函数名@和约定代码,最后是参数表,如:?functionName@@YGXXZ。其中YG是约定代码XXZ是参数表