什么是函数调用约定?

目录

前言

一、函数调用约定的主要内容

二、常见的函数调用约定

1. __cdecl(C Declaration)

2. __stdcall(Standard Call)

3. __fastcall(Fast Call)

4. __thiscall(This Call)

5. __pascal

三、选择合适的调用约定

四、注意事项


前言

函数调用约定(Calling Convention)是在程序设计中定义函数如何调用和返回的一套规则。它规定了函数参数的传递方式、返回值的处理、堆栈的管理以及函数名的修饰方式等。不同的调用约定可能会影响程序的性能和可移植性,因此理解它们对于高效编程和调试非常重要。

一、函数调用约定的主要内容

  1. 参数传递方式

    • 传递顺序:参数是从左到右还是从右到左依次压入堆栈。
    • 传递方式:参数是通过寄存器传递还是通过堆栈传递。
  2. 堆栈管理

    堆栈清理者:调用者(caller)还是被调用者(callee)负责在函数调用结束后清理堆栈上的参数。
  3. 返回值处理

    返回值通常通过寄存器(如 EAX)传递。
  4. 函数名修饰

    编译器如何处理函数名,以支持函数重载和避免命名冲突。

二、常见的函数调用约定

1. __cdecl(C Declaration)

  • 参数传递

    • 顺序:从右到左依次压入堆栈。
    • 方式:通过堆栈传递。
  • 堆栈管理

    • 由调用者清理堆栈。这意味着调用者在函数调用后需要负责移除参数。
  • 返回值

    • 通常通过 EAX 寄存器返回。
  • 函数名修饰

    • 在函数名前加上下划线(如 _FunctionName)。
    • 适用于可变参数函数(如 printf),因为调用者负责堆栈清理,函数本身不需要知道参数的个数。
  • 特点

    • 是 C 语言的默认调用约定。
    • 支持函数重载。
  • 示例

// 声明
int __cdecl add(int a, int b);// 定义
int __cdecl add(int a, int b) {return a + b;
}

2. __stdcall(Standard Call)

  • 参数传递

    • 顺序:从右到左依次压入堆栈。
    • 方式:通过堆栈传递。
  • 堆栈管理

    • 由被调用者清理堆栈。这意味着被调用的函数在返回前负责移除参数。
  • 返回值

    • 通常通过 EAX 寄存器返回。
  • 函数名修饰

    • 在函数名后加上 @ 和参数的字节数(如 FunctionName@8)。
    • 在函数名前加上下划线(如 _FunctionName@8)。
  • 特点

    • 常用于 Windows API 函数。
    • 不支持可变参数函数。
  • 示例

// 声明
int __stdcall add(int a, int b);// 定义
int __stdcall add(int a, int b) {return a + b;
}

3. __fastcall(Fast Call)

  • 参数传递

    • 顺序:前两个双字(DWORD)或更小的参数通过寄存器传递(通常是 ECXEDX),剩余参数从右到左压入堆栈。
  • 堆栈管理

    • 由被调用者清理堆栈。
  • 返回值

    • 通常通过 EAX 寄存器返回。
  • 函数名修饰

    • 在函数名前加上 @,并在函数名后加上 @ 和参数的字节数(如 @FunctionName@8)。
  • 特点

    • 通过使用寄存器传递部分参数,提高调用效率。
    • 适用于参数较少且频繁调用的函数。
  • 示例

// 声明
int __fastcall add(int a, int b);// 定义
int __fastcall add(int a, int b) {return a + b;
}

4. __thiscall(This Call)

  • 适用范围

    • 专用于 C++ 类的成员函数调用。
  • 参数传递

    • 顺序:从右到左依次压入堆栈。
    • 方式:通过堆栈传递参数,this 指针通过寄存器(通常是 ECX)传递
  • 堆栈管理

    • 由被调用者清理堆栈。
  • 返回值

    • 通常通过 EAX 寄存器返回。
  • 函数名修饰

    • 编译器根据具体实现进行修饰,通常与其他调用约定不同。
  • 特点

    • 不能显式指定为函数调用约定,编译器会自动处理。
    • 仅适用于成员函数,不适用于普通函数。
  • 示例

class MyClass {
public:void memberFunction(int a, int b);
};// 编译器会自动使用 __thiscall 调用约定
void MyClass::memberFunction(int a, int b) {// 实现
}

5. __pascal

  • 状态

    • 已被废弃:在现代 Visual C++ 中,__pascal 已经被废弃,不再推荐使用。
  • 特点

    • 参数传递顺序与 __stdcall 类似,但从左到右压入堆栈。
    • 被早期的 Pascal 语言调用约定所采用。
  • 示例

// 已废弃,不推荐使用
int __pascal add(int a, int b);

三、选择合适的调用约定

  1. 默认选择:对于普通的 C/C++ 函数,通常使用 __cdecl,因为它支持可变参数函数(如 printf)。
  2. 性能优化:对于频繁调用且参数较少的函数,可以考虑使用 __fastcall,通过寄存器传递部分参数,提高调用效率。
  3. 与外部库兼容:当调用 Windows API 函数或其他采用特定调用约定的外部库函数时,需使用对应的调用约定(如 __stdcall)。
  4. 类成员函数:不需要手动指定,编译器会自动使用 __thiscall 调用约定。

四、注意事项

  • 一致性:在同一个项目中,确保函数调用约定的一致性,避免因调用约定不匹配导致的程序错误或崩溃。

  • 跨语言调用:当在不同编程语言之间调用函数时,需确保双方使用相同的调用约定,以保证参数传递和堆栈管理的正确性。

  • 编译器支持: 不同的编译器可能对调用约定的支持有所不同,使用前应查阅相应编译器的文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/52059.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[数据集][目标检测]轮胎检测数据集VOC+YOLO格式4629张1类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):4629 标注数量(xml文件个数):4629 标注数量(txt文件个数):4629 标注…

【SQL】删除表中重复数据的方法

很久之前我写入一张sql的数据表,它里面有很多重复的内容。然后我想只保留一条原始数据: 例如上面的时间,出现了很多重复值。 我最初用的是这种方法: SELECT * FROM table_name WHERE primary_key IN (SELECT max(primary_key)F…

仕考网:公务员笔试和面试哪个难?

公务员笔试和面试哪个难?二者之间考察的方向不同,难度也是不同的。 笔试部分因其广泛的知识点和有限的考试时间显得难度更高一些,在笔试环节中,考生需在有限的时间内应对各种问题,而且同时还要面对激烈的竞争,在众多…

栈栈栈专题

一、基础 Leetcode 3174. 清除数字 class Solution { public:string clearDigits(string s) {string st; // 用string模拟栈的行为for(auto& v: s){if(isdigit(v)) st.pop_back();else st v;}return st;} }; 二、进阶 三、邻项消除 四、合法括号字符串 五、…

50Kg大载重长航时油电混动多旋翼无人机技术详解

50Kg大载重长航时油电混动多旋翼无人机技术是一项高度复杂且前沿的研究领域,它结合了燃油发动机的高能量密度和电动机的高效性,旨在提高无人机的续航能力和载重能力。以下是对该技术的详细解析: 产品轴距:2320mm 产品尺寸&#x…

Django+Vue家居全屋定制系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 需要的环境3.2 Django接口层3.3 实体类3.4 config.ini3.5 启动类3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质创作者&…

今年读过最绝的大模型神书死磕这本大模型神书!看完直接脱胎换骨!!

书名📖:《大语言模型:基础与前沿》 该书深入阐述了大语言模型(Large Language Model, LLM)的基本概念和算法、研究前沿以及应用,内容全面且系统性强,适合👨🏻‍&#x1…

【Python系列】FastApi发送Post请求

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

安装 Let‘s Encrypt certbot 生成多个域名免费 https 证书实录(linux pip 方式)

本文记录了我在华为云 EulerOS linux 云主机使用 python pip 方式安装配置 Let’s Encrypt certbot, 并为我的网站的多个域名生成免费 https 证书的整个过程, 包括 python 环境配置, 下载 certbot 及 certbot-nginx, 一次性生成多个域名的证书及注意事项, 以及最后配置 certbot…

k8s配置

一、前期准备 1、修改主机的/etc/hosts文件挟持域名 [rootk8s-master ~]# vim /etc/hosts 192.168.8.199 k8s-master 192.168.8.200 k8s-node1 192.168.8.201 k8s-node2 2、配置yum源 [rootk8s-master ~]# cd /etc/yum.repos.d/ [rootk8s-master yum.repos.d]# vim kubernetes…

软考高项(十八)项目绩效域 ★重点集萃★

👑 个人主页 👑 :😜😜😜Fish_Vast😜😜😜 🐝 个人格言 🐝 :🧐🧐🧐说到做到,言出必行&am…

CRIO与Windows下LabVIEW开发对比

LabVIEW在CRIO和Windows平台上开发时,尽管同属于一个编程环境,但在硬件架构、实时性能、模块化设计等方面存在显著差异。CRIO系统通常应用于工业自动化和嵌入式控制,具有实时操作系统支持和强大的I/O扩展能力;而Windows系统则更适…

网络编程 0904作业

作业 1、多进程多线程并发服务器&#xff0c;再实现一遍&#xff08;重点模型&#xff09; 多进程并发服务器 多进程服务器 PIDserver.c 代码 #include <myhead.h> #define SERPORT 7777 #define SERIP "192.168.19.128" #define BACKLOG 10void hande(int…

【MySQL进阶之路】数据库的操作

目录 创建数据库 字符集和校验规则 查看数据库支持的字符集 查看数据库支持的字符集校验规则 指定字符集和校验规则 在配置文件中配置 查看数据库 显示创建语句 修改数据库 删除数据库 数据库的备份和恢复 备份整个数据库 备份特定表 备份多个数据库 备份所有数据…

C++系列-STL容器之list

STL容器之list list容器的基本结构list容器的特点list容器的优点list容器的缺点 list容器的构造函数list容器的常用接口list赋值操作list大小及空否list访问list迭代器相关list增删查改push and popinsert其它 寄扬州韩绰判官 杜牧〔唐代〕 青山隐隐水迢迢&#xff0c;秋尽江南…

vant 动态查询下拉菜单(可用)

动态查询item项 <van-form submit"onSubmit" ref"formRef"><Title title"企业信息" title-line title-size"19" class"ml-[18px] mb-[18px]"></Title><van-cell-group inset class"py-[18px]&quo…

Python实战项目:天气数据爬取+数据可视化(完整代码)_python爬虫实战

一、选题的背景 随着人们对天气的关注逐渐增加&#xff0c;天气预报数据的获取与可视化成为了当今的热门话题&#xff0c;天气预报我们每天都会关注&#xff0c;天气情况会影响到我们日常的增减衣物、出行安排等。每天的气温、相对湿度、降水量以及风向风速是关注的焦点。通过…

维信小程序禁止截屏/录屏

一、维信小程序禁止截屏/录屏 //录屏截屏,禁用wx.setVisualEffectOnCapture({visualEffect:hidden});wx.setVisualEffectOnCapture(Object object) 测试安卓手机&#xff1a; 用户截屏&#xff0c;被禁用 用户录屏&#xff0c;录制的是空白内容/黑色内容的视频。 二、微信小…

浙大数据结构:01-复杂度2 Maximum Subsequence Sum

数据结构MOOC PTA习题 01-复杂度2 Maximum Subsequence Sum #include <iostream> using namespace std; const int M 100005; int a[M]; int main() {int k;cin >> k;int f 1;for (int i 0; i < k; i){cin >> a[i];if (a[i] > 0)//如果出现大于0则…

【HuggingFace Transformers】OpenAIGPTModel源码解析

OpenAIGPTModel源码解析 1. GPT 介绍2. OpenAIGPTModel类 源码解析 说到ChatGPT&#xff0c;大家可能都使用过吧。2022年&#xff0c;ChatGPT的推出引发了广泛的关注和讨论。这款对话生成模型不仅具备了强大的语言理解和生成能力&#xff0c;还能进行非常自然的对话&#xff0c…