Visual c++函数调用约定的解释(__cdecl,__stdcall,WINAPI等)

本文介绍了调用约定在函数调用过程中的作用,如规范参数传递和返回值处理方式,以及在不同约定下的函数名修饰规则。在微软的VisualC/C++环境下,__cdecl是默认约定,适合可变参数函数,但生成文件较大;__stdcall用于Win32API,不支持可变参数;__fastcall通过寄存器加速调用;Thiscall是C++成员函数的默认约定,参数通过ECX传递。
摘要由CSDN通过智能技术生成

一、正文:

1、什么是调用约定

在一个函数调用另一个函数的时候,有时需要向其传递参数,并且拿到被调用函数运行后的返回值,调用约定就是为了规范这两个过程的实际物理操作,另外还可以在高级语言转为汇编语言的时候指定汇编代码中函数名的修饰方式
即调用约定的作用有:

  1. 规定传参的方式
  2. 规定返回值返回的方式
  3. 规定汇编代码中函数名的修饰方式

更具体一点,传参和返回值返回的“方式”可以被进一步具体为“参数和返回值放在哪里?(堆栈还是寄存器)”以及“调用完成后由谁来清理这些临时数据?(调用函数还是被调用函数)”

2、各种调用约定的具体规则

下面只以 微软visual c/c++ 环境下的部分调用约定举例说明

1)C语言中:

__cdecl

__cdecl调用约定的主要特征是:
1.参数从右向左传递,并放置在堆栈上。
2.堆栈清理由调用方执行。
3.函数名用下划线“_”作为前缀来修饰。

__stdcall(相当于WINAPI)

__stdcall调用约定的主要特征是:
1.参数从右向左传递,并放置在堆栈上。
1.堆栈清理由被调用的函数执行。
1.函数名由一个下划线字符和一个’@'字符以及所需堆栈空间的字节数来修饰。

__fastcall

__fastcall调用约定的主要特征是:
1.前两个需要32位或更少的函数参数被放置在寄存器ECX和EDX中。其余的被从右向左推入堆栈。
2.参数由被调用的函数从堆栈中弹出。
3.函数名由以下方式修饰:在前面加上一个’@‘字符,并附加一个’@'和参数所需的字节数(十进制)。

2)C++中:

Thiscall

Thiscall调用约定的主要特征是:
1.参数从右向左传递,并放置在堆栈上。
2.它被放置在ECX中。堆栈清理由被调用的函数执行。

3、总结

调用约定之间的主要区别:
1.__cdecl是C和c++程序的默认调用约定。这种调用约定的优点是,它允许使用具有可变数量参数的函数。缺点是它创建了更大的可执行文件
2.__stdcall用于调用Win32 API函数。它不允许函数有可变数量的参数
3.__fastcall尝试将参数放入寄存器中,而不是堆栈中,从而使函数调用更快
4.Thiscall调用约定是不使用变量参数的c++成员函数使用的默认调用约定

二、注:

本文为笔者读完Nemanja Trifunovic所著博客《Calling Conventions Demystified》后的总结,原博客链接为:《Calling Conventions Demystified》,更多示例代码和本文未提及的细节请参考原文。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值