c/c++ stdcall cdel fastcall等函数调用约定说明
调用约定(Calling Conventions)是编程中定义函数如何接收参数、返回值以及如何管理堆栈的协议。主要的调用约定包括 __cdecl、__stdcall、__fastcall 和 __thiscall 等。下面将详细介绍这些调用约定的特点及其适用场景。
1. __cdecl 调用约定
- 定义:
__cdecl是 C 语言的默认调用约定,适用于支持可变数量参数的函数。 - 参数传递:
- 参数从右到左压入堆栈。
- 堆栈清理:
- 由调用者负责清理堆栈。这意味着在函数调用后,调用者需要调整堆栈指针以移除参数。
- 返回值:
- 返回值通常存储在 EAX 寄存器中。
- 使用场景:
- 适合需要可变参数的函数,例如
printf。
- 适合需要可变参数的函数,例如
示例
#include <stdio.h>void __cdecl my_function(int a, double b) {printf("a: %d, b: %f\n", a, b);
}int main() {my_function(10, 3.14);return 0;
}
2. __stdcall 调用约定
- 定义:
__stdcall主要用于 Windows API,适合参数数量已知且固定的函数。 - 参数传递:
- 参数同样从右到左压入堆栈。
- 堆栈清理:
- 由被调用者负责清理堆栈,函数返回时会自动清理参数。
- 返回值:
- 返回值通常存储在 EAX 寄存器中。
- 使用场景:
- 主要用于 Windows API 和 DLL 函数。
示例
#include <windows.h>void __stdcall my_function(int a, double b) {// 进行一些操作
}int main() {my_function(10, 3.14);return 0;
}
3. __fastcall 调用约定
- 定义:
__fastcall是一种较快的调用约定,使用寄存器传递前两个参数,可以减少堆栈操作。 - 参数传递:
- 前两个参数通过寄存器(通常是 ECX 和 EDX)传递,其余参数从右到左压入堆栈。
- 堆栈清理:
- 由调用者负责清理堆栈。
- 返回值:
- 返回值通常存储在 EAX 寄存器中。
- 使用场景:
- 适用于对性能有较高要求的场合,尤其是参数数量少且频繁调用的函数。
示例
void __fastcall my_function(int a, int b) {// 进行一些操作
}int main() {my_function(10, 20);return 0;
}
4. __thiscall 调用约定
- 定义:
__thiscall是 C++ 中的默认调用约定,用于类的成员函数。 - 参数传递:
this指针通过 ECX 寄存器传递,其余参数从右到左压入堆栈。
- 堆栈清理:
- 由调用者负责清理堆栈。
- 返回值:
- 返回值通常存储在 EAX 寄存器中。
- 使用场景:
- 主要用于 C++ 的成员函数,适合面向对象编程。
示例
class MyClass {
public:void __thiscall my_method(int a) {// 进行一些操作}
};int main() {MyClass obj;obj.my_method(10);return 0;
}
总结
| 调用约定 | 参数传递顺序 | 堆栈清理方式 | 适用场景 |
|---|---|---|---|
__cdecl | 从右到左压入堆栈 | 调用者清理堆栈 | 可变参数函数 |
__stdcall | 从右到左压入堆栈 | 被调用者清理堆栈 | Windows API 和 DLL继续深入探讨各种调用约定,特别是 __cdecl、__stdcall、__fastcall 和 __thiscall 的具体特点、优缺点、以及在实际开发中的应用场景。 |
5. 各调用约定的优缺点
1. __cdecl
-
优点:
- 支持可变参数函数,可以处理像
printf这样的函数。 - 由于调用者清理堆栈,提供了灵活性。
- 支持可变参数函数,可以处理像
-
缺点:
- 每次调用后,调用者都需要清理堆栈,相对来说效率较低。
- 不适用于需要固定参数数量的情况下,可能导致参数处理上的复杂性。
2. __stdcall
-
优点:
- 堆栈清理的责任在被调用者,简化了调用者的负担。
- 相较于
__cdecl,在非可变参数函数中,堆栈的操作更加高效。
-
缺点:
- 不支持可变参数,不适合需要动态参数数量的函数。
- 在某些平台或编译器中可能不被广泛支持。
3. __fastcall
-
优点:
- 通过寄存器传递参数,减少了堆栈操作,提高了函数调用的效率。
- 特别适合频繁调用的函数,能显著提高性能。
-
缺点:
- 限制了能够通过寄存器传递的参数数量(通常只能前两个)。
- 代码的可移植性会受到影响,因为不同的平台对寄存器分配的处理可能不同。
4. __thiscall
-
优点:
- 适用于 C++ 的类成员函数,
this指针的传递使得成员函数调用更加高效。 - 通过寄存器传递
this指针,减少了堆栈的负担。
- 适用于 C++ 的类成员函数,
-
缺点:
- 仅适用于 C++,对于其他语言或非成员函数不适用。
- 不同编译器可能对其实现有所不同,可能导致兼容性问题。
6. 实际应用中的选择
在实际开发中,选择合适的调用约定非常重要,以下是一些选择调用约定时的考虑因素:
-
函数的参数数量和类型:
- 如果函数参数数量不固定,使用
__cdecl。 - 如果参数数量固定且不多,使用
__stdcall或__fastcall。
- 如果函数参数数量不固定,使用
-
性能要求:
- 对于性能敏感的应用,
__fastcall是更优的选择,因为它减少了堆栈操作。
- 对于性能敏感的应用,
-
平台和编译器支持:
- 确保所选调用约定在目标平台和编译器中被广泛支持,以避免兼容性问题。
-
代码可读性和维护性:
- 选择调用约定时要考虑团队的熟悉程度和代码的可维护性。
7. 其他常见调用约定
除了上述提到的调用约定,以下是一些其他常见的调用约定:
-
__vectorcall:- 用于优化向量和浮点运算,参数通过寄存器传递,适合 SIMD 操作。
-
__regcall:- 允许更灵活的寄存器使用,通常用于特定的性能优化场景。
-
__usercall:- 允许用户自定义堆栈和寄存器的使用,不常用,主要用于高级优化。
8. 总结
调用约定在 C/C++ 编程中扮演着重要的角色,影响着程序的性能、可读性和兼容性。正确的调用约定选择能够有效提高程序的效率,减少错误和不必要的性能损失。开发者在编写代码时,应该根据具体的需求和上下文选择最合适的调用约定,以实现最佳的程序性能和可维护性。
相关文章:
c/c++ stdcall cdel fastcall等函数调用约定说明
调用约定(Calling Conventions)是编程中定义函数如何接收参数、返回值以及如何管理堆栈的协议。主要的调用约定包括 __cdecl、__stdcall、__fastcall 和 __thiscall 等。下面将详细介绍这些调用约定的特点及其适用场景。 1. __cdecl 调用约定 定义&…...
【ROS概述】概念及环境搭建
学习途径: 教程:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 课程视频:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 机器人体系 要完全实现一个机器人的系统研发,几乎是“全栈”开发,…...
MongoDB Shell 基本命令(三)生成学生脚本信息和简单查询
一、生成学生信息脚本 利用该脚本可以生成任意个学生信息,包括学号、姓名、班级、年级、专业、课程名称、课程成绩等信息,此处生成2万名学生,学生所有信息都是给定范围后随机生成。 生成学生信息后,再来对学生信息进行简单查询。…...
java核心技术点都有哪些
1. 面向对象编程(OOP) 核心概念:类、对象、继承、封装、多态。 比喻:面向对象编程就像是在搭建一个积木城堡。类(Class)是城堡的设计图纸,它定义了城堡的结构和功能;对象(…...
4404 - 提高:二分与三分:曲线(三分)
明明做作业的时候遇到了n个二次函数Si(x)=ax22+bx+c,他突发奇想设计了一个新的函数F(x)=max(Si(x)), i=1,2...n。 明明现在想求这个函数在[0,10000]的最小值,要求精确到小数点后四位四舍五入。 输入 输入包含T 组数据 (T<10) ,每组第一行一个整数 n(n≤10000) ,之后n行…...
软件工程--需求分析与用例模型
面向对象分析(ObjectOrientedAnalysis,简称OOA) 分析和理解问题域,找出描述问题域所需的类和对象,分析它们的内部构成和外部关系,建立独立于实现的OOA模型,暂时忽略与系统实现有关的问题。 主要使用UML中的以下几种图…...
预测房价学习
1. 实现函数来方便下载数据 import hashlib import os import tarfile import zipfile import requestsDATA_HUB dict() DATA_URL http://d2l-data.s3-accelerate.amazonaws.com/def download(name, cache_diros.path.join(.., data)):"""下载一个DATA_HUB中…...
电脑无法上网,但是微信、QQ可以正常使用
这种情况一般是由于DNS服务器配置错误,或者已有的DNS服务器无法正常解析地址造成的。 按下winR打开运行,输入ncpa.cpl,点击确定。 在打开的网络连接窗口中找到对应的网卡,双击打开。一般有线网是“以太网”,无线网&am…...
C++11新特性(列表初始化与右值引用折叠与完美转发)
c11 列表初始化c98的{}c11的{}std::initializer_list 右值引用和移动语义左值和右值的概念左值引用和右值引用引用延长临时对象生命周期左值和右值的参数匹配左值引用的主要使用场景移动构造和移动赋值引用折叠完美转发 列表初始化 c98的{} 在C98中,大括号 {} 的使…...
基于SSH的物流运输货运车辆管理系统源码
基于经典的ssh(Spring Spring MVC Hibernate)框架与SaaS(软件即服务)模式,我们为运输企业与物流公司打造了一款开源且易用的车辆管理系统。 该系统主要包含以下核心模块: 档案管理 财务管理 借款管理 保…...
基于RabbitMQ,Redis,Redisson,RocketMQ四种技术实现订单延时关闭功能及其相关优缺点介绍(以12306为主题)
目录 1. 延迟关闭订单 1.1 订单延时关闭功能技术选型 1.1.1 定时任务 1.1.2 RabbitMQ 1.1.3 Redis 过期监听 1.1.4 Redisson 1.1.5 RocketMQ 1.2 RocketMQ订单延时关闭发送方实现 1.3 RocketMQ订单延时关闭的消费方实现 1. 延迟关闭订单 用户发起订单后,如…...
HarmonyOS ArkTS与C++数据类型转换
1. HarmonyOS ArkTS与C数据类型转换 本文介绍了C与TS各自数据类型与互相之间的数据类型转换,在需要使用C模块时可以快速上手对各种数据类型进行转换。 1.1. 概述 HarmonyOS的主力开发语言是ArkTS,也提供了C语言的支持,对于一些能力ÿ…...
腾讯云或阿里云centos7安装Redis,并解决端口无法访问的问题
问题背景 最近自建的网站JeecgFlow在云环境安装redis时候,出现端口无法远程进行访问。 浪费好了好久时间进行排查, 记录一下Redis在云环境centos7环境下如何安装,并且远程访问。 Redis安装 //安装c 用于编译redis yum install gcc-c//在/u…...
【小问题】距离估计和频率估计的方差下界推导出距离估计的方差下界
【1】OFDM Radar Algorithms in Mobile Communication Networks pp34 文章目录 1. 频率和距离之间的关系2. 计算 d ^ \hat{d} d^ 对 n ^ \hat{n} n^ 的导数3. 将频率的方差转化为距离的方差4. 从频率的 CRB 获得 var [ n ^ ] \operatorname{var}[\hat{n}] var[n^]5. 将 …...
Selenium爬虫技术:如何模拟鼠标悬停抓取动态内容
介绍 在当今数据驱动的世界中,抓取动态网页内容变得越来越重要,尤其是像抖音这样的社交平台,动态加载的评论等内容需要通过特定的方式来获取。传统的静态爬虫方法难以处理这些由JavaScript生成的动态内容,Selenium爬虫技术则是一…...
Z-BlogPHP显示错误Undefined array key 0 (set_error_handler)的解决办法
今天打开博客的时候,意外发现页面,打开均显示错误:Undefined array key 0 (set_error_handler)。 博客程序采用的是Z-BlogPHP。百度了一圈没有找到解决办法,在官方论坛里也没找到解决办法。 于是开始自己排查原因。我服务器采用…...
java-实例化一个List,然后添加数据的方法详解
在Java中,实例化一个 List 并向其中添加数据非常简单。List 是一个接口,因此我们通常使用它的常见实现类 ArrayList 或 LinkedList。以下是一些常见的操作方法: ### 1. 使用 ArrayList 实例化并添加数据 java import java.util.ArrayList; …...
【Linux系统】Ubuntu的简单操作
什么是 Ubuntu? Ubuntu(乌帮图)是一个非洲词汇,它的意思是“人性对待他人”或“群在故我在”。Ubuntu发行版将Ubuntu精神带到软件世界之中。 目前已有大量各种各样基于GNU/Linux的操作系统,例如:Debian,SuSE,Gentoo,R…...
标准日志插件项目【C/C++】
博客主页:花果山~程序猿-CSDN博客 文章分栏:项目日记_花果山~程序猿的博客-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 一,项目介…...
SpingBoot原理
SpingBoot原理 在前面十多天的课程当中,我们学习的都是web开发的技术使用,都是面向应用层面的,我们学会了怎 么样去用。而我们今天所要学习的是web后端开发的最后一个篇章springboot原理篇,主要偏向于底 层原理。 我们今天的课程…...
Geb高级等待策略:解决90%的异步加载测试难题
Geb高级等待策略:解决90%的异步加载测试难题 【免费下载链接】geb Very Groovy Browser Automation 项目地址: https://gitcode.com/gh_mirrors/ge/geb Geb作为一款基于Groovy的浏览器自动化工具,其核心优势在于处理现代Web应用中的异步加载场景。…...
揭秘SSHamble工作原理:从认证时序分析到漏洞检测技术
揭秘SSHamble工作原理:从认证时序分析到漏洞检测技术 【免费下载链接】sshamble SSHamble: Unexpected Exposures in SSH 项目地址: https://gitcode.com/gh_mirrors/ss/sshamble SSHamble是一款专注于SSH安全检测的工具,能够深入分析SSH认证过程…...
cv_resnet50_face-reconstruction新手必看:test_face.jpg预处理脚本(自动对齐/白平衡/直方图均衡)附赠
cv_resnet50_face-reconstruction新手必看:test_face.jpg预处理脚本(自动对齐/白平衡/直方图均衡)附赠 本文为初学者详细解析人脸重建项目中test_face.jpg的预处理技巧,包含自动对齐、白平衡和直方图均衡的完整实现代码࿰…...
RexUniNLU国产化适配:麒麟OS+昇腾910B+MindSpore后端兼容性验证报告
RexUniNLU国产化适配:麒麟OS昇腾910BMindSpore后端兼容性验证报告 1. 项目背景与测试目标 RexUniNLU作为一款基于Siamese-UIE架构的零样本自然语言理解框架,在实际部署中需要适配不同的硬件和操作系统环境。本次测试旨在验证该框架在国产化环境中的兼容…...
Qwen2.5-72B-Instruct效果展示:SQL生成、表格转自然语言描述案例
Qwen2.5-72B-Instruct效果展示:SQL生成、表格转自然语言描述案例 1. 模型简介 Qwen2.5-72B-Instruct-GPTQ-Int4是通义千问大模型系列的最新版本,这个720亿参数的指令调优模型在多个领域展现出卓越能力。相比前代Qwen2,它带来了以下显著提升…...
MedGemma应用场景探索:医学教育、科研验证与原型开发
MedGemma应用场景探索:医学教育、科研验证与原型开发 1. 引言:医学AI的多模态革命 在医学影像分析领域,传统方法往往需要专家花费大量时间进行人工解读。MedGemma Medical Vision Lab的出现,为这一过程带来了智能化的解决方案。…...
GME-Qwen2-VL-2B-Instruct模型压缩与加速:使用ONNX和TensorRT提升推理性能
GME-Qwen2-VL-2B-Instruct模型压缩与加速:使用ONNX和TensorRT提升推理性能 你是不是也遇到过这种情况?好不容易把一个大模型部署上线,结果推理速度慢得像蜗牛,用户等得花儿都谢了。特别是像GME-Qwen2-VL-2B-Instruct这种多模态模…...
iPhone换机必看:5种数据迁移方法实测对比(附避坑指南)
iPhone换机数据迁移全攻略:5种方法深度评测与避坑指南 每次拿到新款iPhone的兴奋感,总会被数据迁移的繁琐过程冲淡几分。作为一名经历过多次换机的"果粉",我深刻理解那种既期待新设备又担心数据丢失的复杂心情。本文将基于实测经验…...
联邦学习遇上大语言模型:如何用私有数据训练LLM而不泄露隐私?
联邦学习与大语言模型的隐私保护融合:企业级实践指南 当ChatGPT等大语言模型(LLM)展现出惊人的文本生成能力时,医疗、金融、法律等领域的从业者却面临一个尴尬现实——这些行业最宝贵的私有数据因隐私合规要求,始终无法…...
反诈系统毕设实战:基于规则引擎与实时流处理的高可用架构设计
最近在帮学弟学妹们看毕设,发现不少“反诈系统”项目都卡在了几个老问题上:规则写死在代码里,改一点就要重新上线;数据来了只能批量处理,做不到实时预警;稍微复杂点的场景,误报率就蹭蹭往上涨。…...
