函数调用约定

参数传递过程中,二个问题:

1 当参数多于1个时,按照什么顺序把参数入栈

2 函数调用后 ,由谁把栈恢复原貌

函数调用时,函数调用者依次把参数压栈,然后调用函数,函数调用后,在栈中取得数据,并进行计算。函数调用结束后,

或者调用者或者函数本身修改栈,使栈恢复原貌。

 

stdcall

stdcall调用约定声明函数的格式:

int __stdcall func(int x, int y)

stdcall的调用约定规则:

参数入栈规则: 参数从右向左入栈

堆栈平衡:被调用函数自身修改栈

函数名自动加前导的下划线,后面紧跟一个@符合,其后紧跟着参数的尺寸。

 

 

cdecl调用约定

C语言缺省的调用约定,它声明函数的格式:

int func(int x, int y) 或 int __cdecl func(int x, int y)都可以

cdecl的调用约定规则:

参数入栈顺序: 从右到左

堆栈平衡:调用者修改栈

函数名:前加下划线

由于每次函数调用都要由编译器产生还原栈的代码,所以使用__cdecl方式编译的程序比使用__stdcall编译的程序大很多。

但是__cdecl调用方式是由函数调用者负责清除栈中的函数参数,所以这种方式支持可变参数,比如printf()和Windows API的wsprintf

 

fastcall调用约定
fastcall调用约定声明函数的格式:

int fastcall func(int x, int y)

fastcall调用约定规则:

参数入栈顺序:函数的第一个和第二个参数通过ecx和edx传递,剩余参数从右到左入栈

堆栈平衡:被调用者修改栈

函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸

以fastcall声明执行的函数,具有较快的执行速度,因为函数的前二个参数通过寄存器来传递的。

 

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

参数入栈:参数从右向左入栈

this指针入栈:如果参数个数确定,this指针通过ecx传递给被调用者;如果参数个数不确定,this指针在所有参数压栈后被压入栈。

栈恢复:对参数个数不定的,调用者清理栈,否则函数自己清理栈。

 

函数调用约定:

调用函数时使用的是绝对地址
c语言:
X86:_cdecl _stdcall _fastcall
X64:_fastcall
C++ thiscall: 将类的this指针的地址给寄存器 不压参

 

X86
_cdecl:回收参数列表由主调函数完成
stdcall:回收参数列表由被调函数完成 ret的作用—— 先pop eip 然后 esp 加(add) 一个值(回收参数列表)

fastcall:第一第二参数不压参,直接传递给寄存器 ecx edx 回收参数列表由被调函数完成

X64
fastcall: 多了r8 r9 两个寄存器 可以直接将前四个参数传递给寄存器(rcx rdx r8 r9)

原文链接: https://www.cnblogs.com/liu6666/p/12585637.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    函数调用约定

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/338348

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月1日 下午11:34
下一篇 2023年3月1日 下午11:34

相关推荐