关于 C/C++ 函数调用约定,大多数时候并不会影响程序逻辑,但遇到跨语言编程时,了解一下还是有好处的。

VC 中默认调用是 __cdecl 方式,Windows API 使用 __stdcall 调用方式,在 DLL 导出函数中,为了跟 Windows API保持一致,建议使用 __stdcall 方式。

调用约定跟堆栈清除密切相关。如果写一个汇编函数,给 C/C++ 调用,在 __cdecl 方式下,则汇编函数无需清除堆栈,在 __stdcall 方式下,汇编函数需要在返回(RET)之前恢复堆栈。

C 语言有 __cdecl、__stdcall、__fastcall、naked、__pascal。

C++ 语言有 __cdecl、__stdcall、__fastcall、naked、__pascal、__thiscall,比 C 语言多出一种 __thiscall 调用方式。

在VC中,可以设置默认的调用约定,设置路径为:

Project à Properties à Configuration Properties à C/C++ à Advanced à Call Conversion。

下面详细介绍如上六种调用方式:

1、__cdecl

__cdecl调用约定又称为 C 调用约定,是 C/C++ 语言缺省的调用约定。参数按照从右至左的方式入栈,函数本身不清理栈,此工作由调用者负责,返回值在EAX中。由于由调用者清理栈,所以允许可变参数函数存在,如int sprintf(char* buffer,const char* format,...);。

 

2、__stdcall

__stdcall 很多时候被称为 pascal 调用约定。pascal 语言是早期很常见的一种教学用计算机程序设计语言,其语法严谨。参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在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 不是关键字,程序员不能使用。参数按照从右至左的方式入栈。

http://blog.csdn.net/liujiayu2/article/details/45576803

C/C++函数调用约定与this指针的更多相关文章

  1. C语言函数调用约定

    在C语言中,假设我们有这样的一个函数: int function(int a,int b) 调用时只要用result = function(1,2)这样的方式就可以使用这个函数.但是,当高级语言被编译 ...

  2. Windows x64汇编函数调用约定

    最近在写一些字符串函数的优化,用到x64汇编,我也是第一次接触,故跟大家分享一下. x86:又名 x32 ,表示 Intel x86 架构,即 Intel 的32位 80386 汇编指令集. x64: ...

  3. 【黑客免杀攻防】读书笔记7 - 软件逆向工程基础1(函数调用约定、Main函数查找)

    0x1 准备工作 1.1.准备工具 IDA:交互式反汇编工具 OllyDbg:用户层调试工具 Visual Studio:微软开发工具 1.2.基础知识 C++开发 汇编语言 0x2 查找真正的mai ...

  4. Microsoft函数调用约定

    Microsoft函数调用约定 对于所有调用共有的约定:ebx.ebp.esi.edi都是calle-save,即由被调用的函数负责它们的保存(如果被调用函数用到了这些寄存器的话) 先看函数调用发生了 ...

  5. 关于函数调用约定-thiscall调用约定

    函数调用约定描述了如何以正确的方式调用某些特定类型的函数.包括了函数参数在栈上的分配顺序.有哪些参数将通过寄存器传入,以及在函数返回时函数栈的回收方式等. 函数调用约定的几种类型 stdcall,cd ...

  6. 函数调用约定_stdcall[转]

    关键字 清理堆栈 参数入栈顺序 函数名称修饰(C) __cdecl 调用函数 右 à 左 _函数名 __stdcall 被调用函数 右 à 左 _函数名@数字 __fastcall 被调用函数 右 à ...

  7. c++中的几种函数调用约定(转)

    C++中的函数调用约定(调用惯例)主要针对三个问题: 1.参数传递的方式(是否采用寄存器传递参数.采用哪个寄存器传递参数.参数压桟的顺序等): 参数的传递方式,最常见的是通过栈传递.函数的调用方将参数 ...

  8. 关于 C/C++ 函数调用约定

    关于 C/C++ 函数调用约定,大多数时候并不会影响程序逻辑,但遇到跨语言编程时,了解一下还是有好处的. VC 中默认调用是 __cdecl 方式,Windows API 使用 __stdcall 调 ...

  9. 汇编  cdecl 函数调用约定,stdcall 函数调用约定

    知识点:  cdecl 函数调用约定  stdcall 函数调用约定  CALL堆栈平衡 配置属性--> c/c++ -->高级-->调用约定 一.cdecl调用约定 VC++ ...

随机推荐

  1. python 整型,布尔值,字符串相关

    1.整型(int) 就是所有整数, 2.布尔值(bool) True False 0,"",[],{},(),none为False 3.字符串(str) 字符: 是单一文字符号 字 ...

  2. Java中Scanner类的使用

    一个可以解析基本类型和字符串的简单文本扫描器. 例如,以下代码使用户能够从 System.in 中读取一个数: public class ApiScanner { public static void ...

  3. 团体程序设计天梯赛-练习集-L1-027. 出租

    L1-027. 出租 下面是新浪微博上曾经很火的一张图: 一时间网上一片求救声,急问这个怎么破.其实这段代码很简单,index数组就是arr数组的下标,index[0]=2 对应 arr[2]=1,i ...

  4. 10件5G能实现,但4G不能做的事情

    10件5G能实现,但4G不能做的事情 从三星Galaxy S10 5G手机到OnePlus 7 Pro 5G手机以及更高版本,首批5G手机现已上市.5G网络时代的开启是从小范围内,如果你居住在可以使用 ...

  5. ASP 读取Word文档内容简单示例_组件开发_新兴网络_20161014161610.jpg

  6. 64 求1+2+3+...+n(发散思维能力 )

    题目描述: 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 解题思路: 1)利用&&的短 ...

  7. EhCache缓存页面、局部页面和对象缓存

    页面缓存:SimplePageCachingFilter web.xml <!-- 页面缓存配置,配合ehcache.xml中name为“SimplePageCachingFilter”(默认值 ...

  8. ROPI下载安装

    ROPI下载安装 官方地址 参考文献 安装过程 wget http://num.math.uni-goettingen.de/~m.goerigk/ropi/0.1.0/ropi-0.1.0.tar. ...

  9. 经典alsa 录音和播放程序

    这里贴上虚拟机ubuntu下alsa的录音程序(capture.c)和播放程序(playback.c)的源码. 首先要测试一下自己的ubuntu是否打开了声音.这个可以打开/系统/首选项/声音  来调 ...

  10. Django入门--模型系统(二):常用查询及表关系的实现

    1.常用查询 模型类上的管理器: ** 模型类.objects ** (1)常用一般查询 rs = Student.objects.all() # 查询所有记录,返回Queryset print(rs ...