C/C++中__cdecl、__stdcall、__fastcall函数调用约定

2018年10月9日11:07:34 发表评论 512
摘要

本文主要讲述C/C++中__cdecl、__stdcall、__fastcall三种函数调用约定,包括其参数传递方式、堆栈平衡等主要区别和特点。

C/C++中__cdecl、__stdcall、__fastcall函数调用约定

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是参数表

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: