__stdcall、__cdecl、__fastcall三种函数调用方式
来源:互联网 发布:淘宝客推广大师下载 编辑:程序博客网 时间:2024/05/17 20:57
前些天在cnblogs看到《win32 api 函数参数传递过程》这篇文章,其中只举了push入栈传参的例子,索性又在VC的Debug模式下把几种函数调用方式又看了一遍,这里权当做补充,复习一下函数调用方式。其实原文中说的也没有错,毕竟win32 api是微软的函数,使用__stdcall的方式,传参都是push指令也没有什么问题。
__stdcall是Pascal程序的缺省调用方式,通常Win32API,函数采用从右到左的压栈方式,自己在退出时清空栈。
__cdecl是C/C++程序的缺省的调用方式,按从右至左的顺序压参数入栈,由调用者把参数弹出栈,对于栈由调用者进行维护(可以达到参数可变)。
__fastcall的特点就是快,所以称之为fastcall,关键是通过寄存器来传递参数的(实际上,这种调用方式是采用ecx,edx传送参数的),依旧是自右向左压栈传送,被调用的函数在返回前清理栈。
在VC的编译器中可以通过修改Calling convention来修改函数调用方式。
#include <printf.h> int add(int a, int b) { return a+b;} void main() { int x = 10, y=16; printf("%d", add(x, y)); }
这样子的代码太简单了,没有任何含义这里就不解释了,主要看一下add()函数被在不同调用方式下,会有如何的变化。
__cdecl方式
mov dword ptr [ebp-4], 0A mov dword ptr [ebp-8], 10 mov eax, dword ptr [ebp-8] ;将16传递给eax push eax ;16入栈 mov ecx, dword ptr [ebp-4] ;将10传递给ecx push ecx ;10入栈 call 00401005 ;调用子函数 add esp, 8 ;调用者修正栈空间大小
;子程序 mov eax, dword ptr [ebp+8] ;在栈内操作数据 add eax, dword ptr [ebp+C] ;相加 pop edi ;现场恢复
__stdcall方式
其他跟__cdcel方式差别不大,只是又子程序来清空堆栈。
retn 8 ;子程序自己修正栈空间
__fastcall方式
mov dword ptr [ebp-4], 0A mov dword ptr [ebp-8], 10mov edx, dword ptr [ebp-8] mov ecx, dword ptr [ebp-4]call 00401005 ;调用子函数 mov dword ptr [ebp-8], edx ;现在才是开始对栈进行送数据mov dword ptr [ebp-4], ecx ;不使用push而用mov速度快mov eax, dword ptr [ebp-4] add eax, dword ptr [ebp-8] ;进行加法操作
可以看出__fastcall没有一句push指令,但是依然能够将a和b进行相加,这里就是使用mov传参。除了这三种传参方式,还有很多方式,以后有需要再深入学习吧。
- __stdcall、__cdecl、__fastcall三种函数调用方式
- 函数的调用规则(__cdecl,__stdcall,__fastcall
- 函数调用约定:__cdecl,__stdcall,__fastcall,__thiscall
- 函数的调用约定 __stdcall __cdecl __fastcall
- 函数调用约定 __cdecl __fastcall __stdcall
- 函数调用方式“__stdcall”,"__cdecl"
- 函数调用的区别__stdcall,__cdecl,__fastcall,thiscall,naked call
- 函数命名规则及调用约定(__cdecl,__stdcall,__fastcall)
- 函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)
- 函数调用的区别(__stdcall,__cdecl,__fastcall,thiscall,nake)
- 函数调用详解:__stdcall, __cdecl, __fastcall, thiscall, naked call, __pascal
- 函数调用,__stdcall,__cdecl,__fastcall,thiscall,naked call,__pascal
- 函数调用的区别__stdcall,__cdecl,__fastcall,thiscall,nake
- 函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)
- 函数命名规则及调用约定(__cdecl,__stdcall,__fastcall)
- 函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)
- 函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)
- 函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)
- onCreateDialog方法及示例
- Windows平台下多线程编程基本步骤
- ASP.NET MVC3 学习心得------路由机制
- 各种图像处理类库的比较及选择(The Comparison of Image Processing Libraries)
- js 判断某个对象是否在数组中
- __stdcall、__cdecl、__fastcall三种函数调用方式
- 【小蒙淘金】12.3金银晚评-希腊援助尘埃落定,金银何去何从
- Linux/Windows 下分别编译音视频编解码库ffmpeg的流程和注意事项
- A Walk Through the Forest hdu1142 最短路+简单动规
- Fedora 下 本地LAMP的搭建与文件配置
- Java POI读写Excel文件
- POJ 2049 Finding Nemo
- 手动创建索引及全文检索
- 两个BAT脚本,为了记录里面的几个语法