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

__stdcall、__cdcel和__fastcall

__stdcall__cdecl__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式、栈内数据的清除方式、编译器函数名的修饰规则等。

  在win32应用程序里,宏APIENTRY,WINAPI,都表示_stdcall。


调用协议常用场合
__stdcall:Windows API默认的函数调用协议。
__cdecl:C/C++默认的函数调用协议。
__fastcall:适用于对性能要求较高的场合。


函数参数入栈方式
__stdcall:函数参数由右向左入栈。
__cdecl:函数参数由右向左入栈。
__fastcall:从左开始不大于4字节的参数放入CPU的ECX和EDX寄存器,其余参数从右向左入栈。


C语言编译器函数名称修饰规则
__stdcall:编译后,函数名被修饰为“_functionname@number”。
__cdecl:编译后,函数名被修饰为“_functionname”。
__fastcall:编译后,函数名给修饰为“@functionname@nmuber”。
注:“functionname”为函数名,“number”为参数字节数。函数实现和函数定义时如果使用了不同的函数调用协议,则无法实现函数调用


C++语言编译器函数名称修饰规则
__stdcall:编译后,函数名被修饰为“?functionname@@YG******@Z”。
__cdecl:编译后,函数名被修饰为“?functionname@@YA******@Z”。
__fastcall:编译后,函数名被修饰为“?functionname@@YI******@Z”。
注:“**”为函数返回值类型和参数类型表。函数实现和函数定义时如果使用了不同的函数调用协议,则无法实现函数调用。C语言和C++语言间如果不进行特殊处理,也无法实现函数的互相调用。


__stdcall
__stdcall是Pascal方式清理C方式压栈,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈。VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上”@”和参数的字节数。 int f(void *p) –>> _f@4(在外部汇编语言里可以用这个名字引用这个函数).


__cdecl
__cdecl (The C default calling convention)即C调用约定按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于传送参数的内存栈是由调用者来维护的。另外,在函数名修饰约定方面也有所不同。 _cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。


__fastcall
__fastcall调用的主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈),在函数名修饰约定方面,它和前两者均不同。__fastcall方式的函数采用寄存器传递参数,VC将函数编译后会在函数名前面加上”@”前缀,在函数名后加上”@”和参数的字节数。

转载于:https://www.cnblogs.com/laohaozi/p/8266611.html

相关文章:

  • 温故知新之javascript面向对象
  • Validation Application Block动手实验室
  • 关于 WebRequest.RegisterPrefix
  • 慎用margin系列1---CSS的margin塌陷(collapse) 问题与对策
  • Workarounds一词的翻译
  • jquery ui中的dialog,官网上经典的例子
  • screen 后台实时执行命令
  • IP数据包首部校验和的计算
  • 烂泥:rsync与inotify集成实现数据实时同步更新
  • 使用junitamp;spring修改系统的环境变量,解决docker程序测试问题
  • Eclipse下使用Subversion =subclipse
  • 上传附件
  • check_nginx pnp4nagios 模版
  • 统计挖掘那些事那些情(2)-回归分析spss
  • redis应用之主从架构配置
  • [NodeJS] 关于Buffer
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 【前端学习】-粗谈选择器
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Codepen 每日精选(2018-3-25)
  • Docker入门(二) - Dockerfile
  • golang中接口赋值与方法集
  • JAVA SE 6 GC调优笔记
  • JavaScript设计模式系列一:工厂模式
  • JAVA并发编程--1.基础概念
  • Promise面试题2实现异步串行执行
  • Sequelize 中文文档 v4 - Getting started - 入门
  • socket.io+express实现聊天室的思考(三)
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • windows下使用nginx调试简介
  • 不上全站https的网站你们就等着被恶心死吧
  • 电商搜索引擎的架构设计和性能优化
  • 汉诺塔算法
  • 漂亮刷新控件-iOS
  • 七牛云假注销小指南
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 学习笔记:对象,原型和继承(1)
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • Hibernate主键生成策略及选择
  • zabbix3.2监控linux磁盘IO
  • 阿里云API、SDK和CLI应用实践方案
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​香农与信息论三大定律
  • (1)(1.13) SiK无线电高级配置(五)
  • (2)Java 简介
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (JS基础)String 类型
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)ssm高校实验室 毕业设计 800008
  • (蓝桥杯每日一题)love
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (四)鸿鹄云架构一服务注册中心