常用的调用约定有stdcall,cdecl,fastcall,thiscall,naked call等,以下将 __stdcall、__cdecl和__fastcall三种函数调用协议加以比较,函数调用协议会影响函数参数的入栈方式、栈内数据的清除方式、编译器函数名的修饰规则等。

注: _stdcall是早期16位系统中使用的调用约定,本质是就是stdcall,现行的主要是__stdcall。

  • 调用协议常用场合
    1. __stdcall:Windows API默认的函数调用协议。
    2. __cdecl:C/C++默认的函数调用协议。
    3. __fastcall:适用于对性能要求较高的场合。
  • 函数参数入栈方式
    1. __stdcall:函数参数由右向左入栈。
    2. __cdecl:函数参数由右向左入栈。
    3. __fastcall:从左开始不大于4字节的参数放入CPU的ECX和EDX寄存器,其余参数从右向左入栈。

问题一:__fastcall在寄存器中放入不大于4字节的参数,故性能较高,适用于需要高性能的场合。

  • 栈内数据清除方式
    1. __stdcall:函数调用结束后由被调用函数清除栈内数据。
    2. __cdecl:函数调用结束后由函数调用者清除栈内数据。
    3. __fastcall:函数调用结束后由被调用函数清除栈内数据。

问题一:不同编译器设定的栈结构不尽相同,跨开发平台时由函数调用者清除栈内数据不可行。

问题二:某些函数的参数是可变的,如printf函数,这样的函数只能由函数调用者清除栈内数据。

问题三:由调用者清除栈内数据时,每次调用都包含清除栈内数据的代码,故可执行文件较大。

  • C语言编译器函数名称修饰规则
    1. __stdcall:编译后,函数名被修饰为“_functionname@number”。
    2. __cdecl:编译后,函数名被修饰为“_functionname”。
    3. __fastcall:编译后,函数名给修饰为“@functionname@nmuber”。

注:“functionname”为函数名,“number”为参数字节数。

注:函数实现和函数定义时如果使用了不同的函数调用协议,则无法实现函数调用。

  • C++语言编译器函数名称修饰规则
    1. __stdcall:编译后,函数名被修饰为“?functionname@@YG******@Z”。
    2. __cdecl:编译后,函数名被修饰为“?functionname@@YA******@Z”。
    3. __fastcall:编译后,函数名被修饰为“?functionname@@YI******@Z”。

注:“******”为函数返回值类型和参数类型表。

注:函数实现和函数定义时如果使用了不同的函数调用协议,则无法实现函数调用。

C语言和C++语言间如果不进行特殊处理,也无法实现函数的互相调用。

__stdcall、__cdcel、__fastcall 调用的更多相关文章

  1. C调用约定__cdecl、__stdcall、__fastcall、__pascal分析

    参考原文地址:https://www.cnblogs.com/yenyuloong/p/9626658.html C/C++ 中不同的函数调用规则会生成不同的机器代码,产生不同的微观效果,接下来让我们 ...

  2. __cdecl、__stdcall、__fastcall 与 __pascal 浅析

    call 指令与 retn 指令 首先我们得了解 CALL 和 RETN 指令的作用,才能更好地理解调用规则,这也是先决条件. 实际上,CALL 指令就是先将下一条指令的 EIP 压栈,然后 JMP ...

  3. __stdcall,__cdecl,__fastcall的区别

    __stdcall,__cdecl,__fastcall的区别 标签: dll编译器pascalclassimportinitialization 2009-12-09 15:07 10472人阅读  ...

  4. __cdecl、__stdcall、__fastcall、thiscall 进栈、出栈区别

    https://en.wikipedia.org/wiki/X86_calling_conventions https://msdn.microsoft.com/en-us/library/984x0 ...

  5. __stdcall,__cdecl,__fastcall,_stdcall,_cdecl,_fastcall 区别简介[转]

    今天写线程函数时,发现msdn中对ThreadProc的定义有要求: DWORD WINAPI ThreadProc(LPVOID lpParameter);   不解为什么要用WINAPI宏定义,查 ...

  6. 闲话__stdcall, __cdecl, __fastcall出现的历史背景以及各自解决的问题

    可以认为最先由微软搞出来了__stdcall, 其实就是和WINAPI的声明是一样的,入栈顺序是从右到左,函数返回时,会进行出栈操作. PASCAL语言是非常古老的编程语言,在C语言之前,因此在当时的 ...

  7. 【C/C++开发】__stdcall,__cdecl,__fastcall的区别

    __stdcall和__cdecl的区别 __stdcall和__cdecl是两种函数名字修饰.(注意是连续的两个下划线) Windows上 windows上不管是C还是C++,默认使用的都是__st ...

  8. 关于__stdcall和__cdecl调用方式的理解

    __stdcall和__cdecl都是函数调用约定关键字,先给出这两者的区别,然后举实例分析: __stdcall:参数由右向左压入堆栈:堆栈由函数本身清理. __cdecl:参数也是由右向左压入堆栈 ...

  9. printf不定参数

    title: printf不定参数 tags: C ARM date: 2018-10-21 12:14:58 --- 不定参数的传递 函数调用时参数传递是使用堆栈来实现的,参数入栈顺序是从右向左,在 ...

随机推荐

  1. 学习shell的第二天

    重定向和管道符: 1.重定向 程序 = 指令 + 数据            命令    变量  在程序中,数据如何输入?又如何输出?  数据输入:键盘  --  标准输入,但是并不是唯一输入方式:  ...

  2. hue改下载行数

    参考: https://blog.csdn.net/lingbo229/article/details/85991230 修改hue所在机器的默认配置后,重启hue即可 find / -name be ...

  3. 用ufile和S3代替hdfs存储数据

    一,添加ufile需在配置中添加: core-site.xml添加如下配置:<property><name>fs.ufile.impl</name><valu ...

  4. [转帖]英特尔的 ME 或侵犯 Minix3 的自由软件许可证

    英特尔的 ME 或侵犯 Minix3 的自由软件许可证 [日期:2017-12-11] 来源:Linux公社  作者:非非然 [字体:大 中 小] https://www.linuxidc.com/L ...

  5. Java第六周课堂示例总结

    一.如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算? public class InitializeBlockDemo { /** * @param args */ pub ...

  6. Luogu P3520 [POI2011]SMI-Garbage

    题目 把要变边权的边拿出来找欧拉回路就行了.正确性显然,因为一条边经过两次相当于对欧拉回路度数的奇偶性没有影响. 然后把一个个小环输出即可,具体的我也不知道怎么输,题目没讲清楚,我按着题解的来的. # ...

  7. CSS(下)

    目录 CSS(下) CSS属性相关 宽和高 字体属性 背景属性 边框 border-radius display属性 CSS盒子模型 margin外边距 padding内填充 浮动(float) 限制 ...

  8. 什么是 Serverless 应用引擎?优势有哪些?

    Serverless 应用引擎(Serverless App Engine,简称 SAE)是面向应用的 Serverless PaaS 平台,能够帮助 PaaS 层用户免运维 IaaS,按需使用,按量 ...

  9. 第二章 单表查询 T-SQL语言基础(1)

    单表查询(1) 本章:逻辑查询处理,特定的SELECT查询生成正确的结果集而要经历的一系列逻辑阶段;单表查询的其他方面,包括:运算符,空值(NULL),字符的处理和临时数据,分级(ranking),C ...

  10. 使用xpath爬取猫眼电影排行榜

    最近在学习xpath,在网上找资料的时候,发现一个新手经常拿来练手的项目,爬取猫眼电影前一百名排行的信息,很多都是跟崔庆才的很雷同,基本照抄.这里就用xpath自己写了一个程序,同样也是爬取猫眼电影, ...