函数调用约定——__cdecl与__stdcall

1.定义

函数调用约定,也称函数调用协议,是指在函数调用时,确定函数参数如何传递给被调用的函数,以及如何返回结果值给调用者的一系列规则。也就是函数的调用者与被调用者之间如何传参以及如何恢复栈平衡

2.职责

  1. 规定了函数参数的压栈顺序,即有多个参数时,按照什么顺序进行压栈;
  2. 规定了由谁负责清理栈,即函数调用后,是调用函数还是被调用函数来把栈恢复成调用前的样子。

3.种类

函数调用约定有很多,本文简要讨论以下两种:
(说明:调用者caller,即调用函数;被调用者callee,即被调用函数)

  1. __cdecl
  • 调用者:
    • 将函数参数从右向左压栈;
    • 调用结束后,负责调整栈指针以清除栈中的参数。这意味着调用者需要手动管理栈中的内容,确保栈的前后状态是正确的。
  • 被调用者:
    • 读取栈中参数以执行函数功能;
    • 功能执行完毕后将结果返回给调用者,不负责清理栈。
  1. __stdcall
  • 调用者:
    • 同样将函数参数从右向左压栈;
    • __cdecl不同,调用者不负责在调用结束后清理栈中的参数。
  • 被调用者:
    • 同样读取栈中参数以执行函数功能;
    • 调用结束后,除了负责调整栈指针以清除栈中的参数外,还要清理栈中的参数,这意味着由被调用者来管理函数执行期间所使用的栈空间。

4.使用场景

__cdecl由于其灵活性(调用者可以传递任意数量的参数,即使与函数声明不符也不会在编译时产生错误)而被C和C++编译器用作默认的函数调用约定。而__stdcall则常用于Windows API等需要严格参数匹配和自动栈管理的场合,特别是在Windows API和需要跨编译器、跨平台兼容性的场合中。


参考资料:

chatgpt

posted @   Hell0er  阅读(126)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示