博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Calling Convention的总结
阅读量:4191 次
发布时间:2019-05-26

本文共 1105 字,大约阅读时间需要 3 分钟。

因为经常需要和不同的Calling Convention打交道,前段时间整理了一下它们之间的区别,如下:

 

清理堆栈

参数压栈顺序

命名规则 (MSVC++)

备注

Cdecl

调用者 (Caller)

从右往左 

FuncName

因为是调用者清理Stack,因此允许变参 (printf)

Pascal

被调用者 (Callee)

从左往右 

已不再支持

__pascal, __fortran, __syscall

Stdcall

被调用者 (Callee)

从右往左

_FuncName@N

N表示所有参数大小字节数,如4

一般在Windows APICOM中使用,也是.NETNative代码调用的缺省Calling Convention。

顺便提一下,Windows中API的Calling Convention所使用到的WINAPI宏在PC机上是__stdcall,而在WinCE上则是__cdecl,并非一成不变。

Fastcall (Microsoft)

被调用者 (Callee)

从右往左

@FuncName@N

N表示参数大小字节数,如4

Stdcall类似,但是会选择两个从左往右数最先可以放在寄存器里面的参数放在ECXEDX

Thiscall (Microsoft)

被调用者 (Callee)

从右往左

编译器会将名字,类名,参数等编码到名字里面,具体方式和编译器相关,如:

 

?Func@MyClass@@QAEXPAX@Z

基本上等价stdcall, 除了this指针用ECX传递

 

 

 

 

 

 

稍微解释一下其中不是特别明显的几个列的意义:

解释

清理堆栈

调用函数的时候,一般的参数都被调用者压栈(除了需要用寄存器传递的参数除外)。问题在于,谁来清理调用者压入堆栈的参数内容,是调用者还是被调用者。清理的意义是将压入的参数退栈,从机器的角度来讲则是调整堆栈指针ESP。当调用者也负责清理栈的时候,由于调用者知道实际参数的个数,因此可以正确处理变参的情况(如printf),就算是压入的参数和所期望的参数不一致也不会造成栈的不平衡,这正是printf可以很容易直接传入不同参数,而Windows API必须显式传入va_list参数(如FormatMessage)来获得变参能力的原因。

压栈顺序

参数被压栈的时候,如果有多个参数,参数可以以从左往右依次压入的顺序压入,也可以以从右往左的顺序,不同的Calling Convention之间存在区别。

 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1852736

你可能感兴趣的文章
我们需要实践来建立过程
查看>>
人们不喜欢过程
查看>>
UML很棒但是过于庞大了
查看>>
虚拟大教堂的探索
查看>>
使用xml语言自动导入测试需求到开源测试工具testlink
查看>>
软件测试时代发展5周年的一个总结
查看>>
软件测试工程师的职业发展综述
查看>>
第33次(北京)软件测试交流会定于11月4日(周日)在北京举行
查看>>
关于软件测试人员绩效考核的讨论
查看>>
国内质量意识的变更过程
查看>>
测试时代软件测试交流会4月15日北京举行
查看>>
测试时代论坛中测试新手的职业发展困惑
查看>>
软件测试过程的监控方法
查看>>
软件企业质量保证的基石――QA、QC的良性协作
查看>>
TDD的三条规则(中英对照)
查看>>
敏捷软件开发基础:进行有效的客户协作
查看>>
敏捷软件开发基础: 持续集成环境的构建
查看>>
A draft TOC of 嵌入式电信软件敏捷开发实践
查看>>
"Balancing Agility and Discipline" 中文版——《平衡敏捷与规范》终于要出版了
查看>>
软件思考系列之二
查看>>