您的位置:首页 > 其它

函数调用与约定

2014-08-20 15:19 232 查看
此前看教程,函数调用与约定。。看完之后不明不白的。。这个东西到底有什么用。。现在 也是不太明白。。只是觉得 这个就像是使用了一些系统预先设置 的规则 卡一样。。

可能理解的有些不准确。。欢迎指出。。今天又在看那个教程。。百度搜了下。。看到以为CSDN的大牛~有文章介绍了这个知识点。。于是就毫不留情的搬了过来。。刚好自己的博客也刚建。。。收藏知识库了~多谢作者~

函数调用约定决定以下内容:

1)函数参数的压栈顺序

2)由调用者还是被调用者把参数弹出栈

3)以及产生函数修饰名的方法

一般WIN32的函数都是__stdcall

#define CALLBACK __stdcall

#define WINAPI  __stdcall

WINDOWS的函数调用时需要用到栈(STACK,一种先入后出的存储结 构)。

当函数调用完成后,栈需要清除,这里就是问题的关键,如何清除?如果我们的函数使用了_cdecl,那么栈的清除工作是由调用者,用COM的术语来 讲就是客户来完成的。这样带来了一个棘手的问题,不同的编译器产生栈的方式不尽相同,那么调用者能否正常的完成清除工作呢?答案是不能。如果使用 __stdcall,上面的问题就解决了,函数自己解决清除工作。所以,在跨(开发)平台的调用中,我们都使用__stdcall(虽然有时是以 WINAPI的样子出现)。那么为什么还需要_cdecl呢?当我们遇到这样的函数如fprintf()它的参数是可变的,不定长的,被调用者事先无法知 道参数的长度,事后的清除工作也无法正常的进行,因此,这种情况我们只能使用_cdecl。到这里我们有一个结论,如果你的程序中没有涉及可变参数,最好 使用__stdcall关键字。

原文作者介绍的很详细,原文末尾可以看到作者参考了大量专业书籍。。这种精神~致敬~

原文地址在文章末尾处。

我稍微记录下。。如果有不对的,请指出。谢谢

1. __cdecl

常用,为系统缺省的调用方式 参数的压入顺序为从右往左,栈上的参数由调用者清除

2. __stdcall

调用广泛 ,大多数WIN API都是这种调用方式,参数的压入顺序为从右往左,栈上的参数由函数清除

3. __fastcall

使用较少,参数的压入顺序为从右往左,把第一第二个参数放入寄存器(ECX ,EDX)中。。栈上的参数由函数清除

【__fastcall也有__stdcall的缺点:不支持可变参数个数的函数。】

4. 一些过时的调用约定 __pascal, __fortran 和__syscall是三种已经过时的调用约定,MSDN的建议是使用WINAPI宏,也就是__stdcall来代替原来的PASCAL和 __far __pascal。

5. thiscall

在VS2005之前,仅应用于C++的成员函数:

把this指针存放于CX寄存器,参数从右到左压栈,由函数来负责清除参数。 【不支持可变参数】

6. __clrcall

只能被托管代码(managed code)调用

7. Naked 函数调用

这是VC 里一种给高级用户使用的调用约定,它实际上就是没有规范,用户可以通过内嵌汇编来实现任意想要得调用约定。由于我们平时编程时基本上不会去使用它,

参考自http://blog.csdn.net/zjwoody/article/details/7887988

稍有增删
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: