当前位置: 首页 > news >正文

C++中cdecl、stdcall、fastcall、thiscall异同——10分钟弄清

以下是 C++ 中四种常见调用约定(cdeclstdcallfastcallthiscall)的对比说明,结合示例和场景分析帮助理解:


  1. cdecl(C 声明约定)
  • 参数传递:从右向左压栈(如 func(a, b) 先压 b 再压 a
  • 清栈方:调用者清理栈(调用后需执行 add esp, X
  • 适用场景:C/C++ 默认约定,支持可变参数(如 printf
  • 汇编特征:函数名前加 _(如 _func
  • 示例:
    int __cdecl add(int a, int b) { return a + b; }
    // 调用后编译器生成:add esp, 8  (清理两个 int 参数)
    

  1. stdcall(标准调用约定)
  • 参数传递:从右向左压栈(同 cdecl
  • 清栈方:被调函数自己清栈(函数末尾用 ret X 指令)
  • 适用场景:Windows API 标准约定(如 MessageBox
  • 汇编特征:函数名格式为 _func@XX 为参数总字节数)
  • 示例:
    int __stdcall sub(int a, int b) { return a - b; }
    // 函数返回时执行:ret 8  (自动清理参数)
    

  1. fastcall(快速调用约定)
  • 参数传递:
    • 前两个参数通过寄存器传递(ECXEDX
    • 剩余参数从右向左压栈
  • 清栈方:被调函数清理栈(同 stdcall
  • 适用场景:性能敏感场景(小型参数函数)
  • 汇编特征:函数名前加 @(如 @func@8
  • 示例:
    int __fastcall mul(int a, int b) { return a * b; }
    // 编译后:a 存入 ECX,b 存入 EDX,无需压栈 
    

  1. thiscall(C++ 成员函数约定)
  • 参数传递:
    • this 指针通过 ECX 寄存器传递
    • 其他参数从右向左压栈
  • 清栈方:被调函数清理栈(同 stdcall
  • 适用场景:C++ 类成员函数的默认约定(不可显式指定)
  • 汇编特征:无特殊修饰,但隐含 this 指针
  • 示例:
    class Calculator {
    public:int __thiscall div(int b) { return value / b; } // 编译器自动添加 __thiscall 
    };
    // 调用时:this 存入 ECX,参数 b 压栈
    

对比总结

特性cdeclstdcallfastcallthiscall
参数顺序从右向左压栈从右向左压栈寄存器 + 从右向左压栈this(ECX)+ 从右向左压栈
清栈方调用者 (add esp, X)被调函数 (ret X)被调函数 (ret X)被调函数 (ret X)
适用场景可变参数函数Windows API高频调用小函数C++ 类成员函数
函数修饰_func_func@8@func@8无特殊修饰

关键差异示例

// cdecl:调用者清栈
sum = __cdecl add(1, 2);  // 汇编:push 2; push 1; call _add; add esp, 8 // stdcall:函数自己清栈 
result = MessageBox(nullptr, "Hello", "Title", MB_OK); // 汇编:call _MessageBoxA@16 // thiscall:隐含 this 传递 
Calculator calc;
calc.div(3);  // 汇编:mov ecx, &calc; push 3; call ?div@Calculator@@QAEHH@Z 

实际行为可能因编译器优化略有差异,调试时观察寄存器/栈变化可验证调用约定。

http://www.dtcms.com/a/365630.html

相关文章:

  • linux0.12 head.s代码解析
  • Alpha World赞助Hello Blockchain Thailand,AWT成为全球共识焦点
  • 袋鼠云产品功能更新报告14期|实时开发,效率再升级!
  • 【IQA技术专题】NIQE代码讲解
  • VMWare上搭建分布式Hadoop集群
  • STM32F103按钮实验
  • 大语言模型领域最新进展
  • 笔记:卷积神经网络(CNN)
  • rust学习之开发环境
  • 从 0 到 1 吃透 Nacos:服务发现与配置中心的终极实践指南
  • 阅兵时刻,耐达讯自动化RS485 转 Profinet 网关助力矿山冶金连接迈向辉煌
  • BurpSuite_Pro_V2024.6使用教程-Burp Suite代理设置详解
  • 张琦《认知破局》读书笔记
  • 内存保护单元MPU
  • 用资产驱动方法构建汽车网络安全档案
  • 中科米堆CASAIM自动化三维测量设备测量汽车零部件尺寸质量控制
  • php:PHP 8 新特性深度解析与实战应用:提升开发效率的关键技巧
  • 2025全球及中国汽车VDA电池模组:头部企业市场排名与占有率独家揭晓
  • 视频打不开怎么办?教你一键修改默认打开方式
  • Java全栈工程师的面试实战:从基础到复杂问题的完整解析
  • Jira vs. GitLab Issues vs. Redmine:终极选型与成本分析
  • 金牛区好办公室国际数字影像产业园企业服务
  • 《深入解析:Kubernetes网络策略冲突导致的跨节点服务故障排查全过程》
  • Streamable HTTP
  • 《录井工程与管理》——第四章单井地质剖面建立录井技术
  • 新手向:JavaScript性能优化实战
  • 免费的PDF工具箱软件,免费PDF转word,PDF合并,PDF24下载,24个功能
  • JVM调优与常见参数(如 -Xms、-Xmx、-XX:+PrintGCDetails) 的必会知识点汇总
  • RPA行业的主要玩家有哪些?
  • 告别剪辑烦恼!3个超实用技巧,让你的视频瞬间高级起来