注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

函数调用约定的说明  

2016-11-01 11:30:58|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

函数调用约定的说明

一直沿用着在32位下的几种调用方式:

1__cdeclC调用约定.The C default calling conventionC/C++ 缺省调用方式

  1)压栈顺序:函数参数从右到左

  2)参数栈维护:由调用函数把参数弹出栈,传送参数的内存栈由调用函数来维护

  (正因为如此,实现可变参数vararg的函数(printf)只能使用该调用约定)

  3)函数修饰名约定:VC将函数编译后会在函数名前面加上下划线前缀

  4)每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大

2__stdcall (Pascal方式清理C方式压栈,通常用于Win32 Api)

  1)压栈顺序:函数参数从右到左的压栈顺序

  2)参数栈维护:被调用函数把参数弹出栈(在退出时清空堆栈)

 3)函数修饰名约定:VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上"@"和参数的字节数

    ex. VC: int f(void *p) (编译后)-> _f@4(在外部汇编语言里可以用这个名字引用这个函数)

3 __fastcall (快速调用约定,通过寄存器来传送参数)

  1)压栈顺序:ECXEDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送

  2)参数栈维护:被调用函数在返回前清理传送参数的内存栈

  3)函数修饰名约定:VC将函数编译后会在函数名前面加上"@"前缀,在函数名后加上"@"和参数的字节数

4thiscall (本身调用,仅用于“C++”成员函数)

  1)压栈顺序:this指针存放于CX/ECX寄存器中,参数从右到左的压栈顺序

  2)thiscall不是关键词,因此不能被程序员指定

5naked call (裸调)

  1)当采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来

    保存ESIEDIEBXEBP寄存器,退出函数时则产生代码恢复这些寄存器的内容

   (这些代码称作 prolog and epilog code,一般,ebp,esp的保存是必须的)

  2)naked call不产生这样的代码。naked call不是类型修饰符,故必须和_declspec共同使用

 关键字 __stdcall__cdecl__fastcall(1-3)可以直接加在要输出的函数前。

 它们对应的命令行参数分别为/Gz/Gd/Gr。缺省状态为/Gd,即__cdecl

 要完全模仿PASCAL调用约定首先必须使用__stdcall调用约定,函数名修饰约定可通过其它方法模仿WINAPI宏,Windows.h支持该宏,它可以将出函数翻译成适当的调用约定,

 WIN32中,它被定义为__stdcall。使用WINAPI宏可以创建自己的APIs

 但是在今天面试一个小帅哥时,他提出了一点说在X64下调用方式统一了,他们在使用的时候更改调用约定会出现错误。瞬间觉得知识教条化了,需要更新了,小帅哥给在手机上看了一个网页,果然如此。

回来认真查找了一下,发现了如下的说明:

x86 x64 的两个重要修改是:64 位寻址功能和一组平面的用于常规使用的 16 64 位寄存器。对于展开的寄存器集,x64 仅使用 __fastcall 调用约定和基于 RISC 的异常处理模型。__fastcall 模型使用寄存器(对前四个变量)和堆栈帧传递其他参数。

用网上的资料上说,到了64位,硬件和编译器突然发现自己阔了好多,手头钱多了,空间大了,原来需要这么处理那么处理的,不都是因为“钱”么,现在哥有钱了,不再乎了。所以全都用寄存器来处理,这样,这样就没啥这样的了。所以就留一个调用方式得了。

另外需要注意的是:

GCC64位的处理和VC64位处理是有细微差别的,千万不要大意。具体看:

http://blog.sina.com.cn/s/blog_6f6769b50100uhzz.html

下面是官方的说明:

https://msdn.microsoft.com/zh-cn/library/ms235286

要与时俱进啊。

 

  评论这张
 
阅读(28)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017