X86/X64 函数调用约定
C 语言有 __cdecl、__stdcall、__fastcall、naked、__pascal。
C++ 语言有 __cdecl、__stdcall、__fastcall、naked、__pascal、__thiscall,比 C 语言多出一种 __thiscall 调用方式。
下面详细介绍如上六种调用方式:
1、__cdecl
__cdecl调用约定又称为 C 调用约定,是 C/C++ 语言缺省的调用约定。表示C语言默认的函数调用方法,参数按照从右至左的方式入栈,函数本身不清理栈,此工作由调用者负责,返回值在EAX中。由于由调用者清理栈,所以允许可变参数函数存在,如int sprintf(char* buffer,const char* format,...);。
2、__stdcall
__stdcall 很多时候被称为 pascal 调用约定。是StandardCall的缩写,是C++的标准调用方式。pascal 语言是早期很常见的一种教学用计算机程序设计语言。所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是this指针。这些堆栈中的参数由被调用的函数在返回时清除,使用的指令是 retnX,X表示参数占用的字节数,CPU在ret之后自动弹出X个字节的堆栈空间。称为自动清栈。函数在编译的时候就必须确定参数个数,并且调用者必须严格的控制参数的生成,不能多,不能少,否则返回后会出错。返回值在EAX中
3、__fastcall
顾名思义,__fastcall 的特点就是快,因为它通过 CPU 寄存器来传递参数。他用 ECX 和 EDX 传送前两个双字(DWORD)或更小的参数,剩下的参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在 EAX 中。
4、naked
naked 是一个很少见的调用约定,一般不建议使用。编译器不会给这种函数增加初始化和清理代码,更特殊的是,你不能用return返回返回值,只能用插入汇编返回结果,此调用约定必须跟 __declspec 同时使用。例如定义一个求和程序,如__declspec(naked) int add(int a,int b);。
5、__pascal
这是 pascal 语言的调用约定,跟 __stdcall 一样,参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在EAX中。VC 中已经废弃了这种调用方式,因此在写 VC 程序时,建议使用 __stdcall 代替。
6、__thiscall
这是 C++ 语言特有的一种调用方式,用于类成员函数的调用约定。如果参数确定,this 指针存放于 ECX 寄存器,函数自身清理堆栈;如果参数不确定,this指针在所有参数入栈后再入栈,调用者清理栈。__thiscall 不是关键字,程序员不能使用。参数按照从右至左的方式入栈。
注意
_fastcall 和 __thiscall涉及的寄存器由编译器决定,因此不能用作跨编译器的接口。所以Windows上的COM对象接口都定义为_stdcall调用方式。
针对参数列表类型的函数。即可变参数函数:
为什么只有__cdecl的调用约定支持可变参数,而__stdcall就不支持?
实际上__cdecl和__stdcall函数参数都是从右到左入栈,它们的区别在于由谁来清栈,__cdecl由外部调用函数清栈,而__stdcall由被调用函数本身清栈, 显然对于可变参数的函数,函数本身没法知道外部函数调用它时传了多少参数,所以没法支持被调用函数本身清栈(__stdcall), 所以可变参数只能用__cdecll.
另外还要理解函数参数传递过程中堆栈是如何生长和变化的,从堆栈低地址到高地址,依次存储 被调用函数局部变量,上一函数堆栈桢基址,函数返回地址,参数1, 参数2, 参数3..
参数传递顺序
调用堆栈清理
最新文章
- 响应式Web设计 - 布局
- 在MyBook Live上部署svn
- GDB调试笔记
- Storm系列(十一)架构分析之Supervisor-管理Worker进程的事件线程
- HDOJ 1070 Milk(水题,考英文的)
- cocos2d-js(二)cocos2d-js的基本语法与类的简介
- Centos 搭建邮箱系统
- sklearn数据库-【老鱼学sklearn】
- 骨灰级玩家体验带你测试体验天使纪元OL折扣端
- 递归可视化之汉诺塔的动画实现(turtle海龟)
- ML.NET 示例:回归之价格预测
- MongoDB与关系型数据库 区别
- crontab使用说明及例子程序
- java空指针异常
- Linux动态共享库
- VMware + LInux + Xshell 连接环境设置(心得体会)
- django创建第一个项目helloworld
- bzoj 3144 [Hnoi2013]切糕——最小割
- DataGridView,Dataset,DataTable,DataRow等使用心得
- Unity 2D游戏开发教程之为游戏场景添加多个地面