调用约定 小结
来源:互联网 发布:医疗器械软件测试报告 编辑:程序博客网 时间:2024/05/19 15:25
1.C调用约定 _cdecl
从右到左将函数参数入栈,调用方负责平衡栈
void demo_cdecl(int w,int x,int y,int z);
push 4push 3push 2push 1call demo_cdecladd esp,16
;demo_cdecl(1,2,3,4);gnu(gcc g++采用这种技巧将函数参数放到栈上)mov [esp+12],4mov [esp+8],3mov [esp+4],2mov [esp],1call demo_cdecl
2.标准调用约定 _stdcall
void _stdcall demo_stdcall(int w,int x,int y);
从右到左的顺序将参数入栈,函数结束执行时,又被调用的函数负责删除栈中的函数参数,平衡栈。
对被调用函数而言,必须清楚知道栈上有多少个参数,只有在函数接受的参数数量固定才可行。
所以对于printf这种接受可变数量的参数的函数不能使用stdcall
//demo_stdcall中有三个参数 占用了 3*sizeof(int)=12 (在32位体系结构的cpu上) x86编译器使用ret指令//从栈顶提取返回地址并平衡栈指针,清除参数.ret 12
3.x86 fastcall
fastcall属于stdcall的一个变体,向cpu寄存器最多传递两个参数。
msvc++ 和 gnu的gcc/g++能够识别fastcall的修饰符,如果指定fastcall,前两个参数将分别位于ECX,EDX寄存器中,剩余的参数类似于stdcall约定方式入栈,同样 fastcall函数(被调用方)负责平衡栈
void fastcall demo_fastcall(int w,int x,int y,int z);
;demo_fastcall(1,2,3,4)push 4push 3mov edx,2mov ecx,1call demo_fastcall
4.C++调用约定
ms v c++提供this call调用约定,将this传递到ECX寄存器中,并且和stdcall中一样,它要求非静态成员函数清除栈中的参数。
gnu g++编译器将this看成是任何非静态成员函数中的第一个隐含参数,而在其他方便与cdecl约定相同,因此对于使用g++编译的代码来说,在调用非静态成员函数之前,this被放置到栈顶,切调用方负责在啊含糊返回时删除栈中的参数(至少有个一)。
5.其他调用约定
调用约定是特定于语言、编译器、cpu的。
对于 优化代码,定制汇编语言和系统调用等情况需要特别注意。
0 0
- 调用约定 小结
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 调用约定
- 常用连续型分布介绍及R语言实现
- Fragment(1)-生命周期方法与Fragment视图是否可见间的细节
- 零基础入门学习Python(5):列表
- Swift- lazy 懒加载
- VirtualBox共享文件夹
- 调用约定 小结
- LeetCode---Restore IP Addresses
- eclipse中的项目鼠标右键卡死
- os x el capitan 后竟然无法使用Axure RP
- 写一个memcpy()函数你能拿几分?
- Visual Studio 2013 智能提示功能消失解决办法
- spark RDD transformation和action操作
- Bucket sort 桶排序(含EOF)
- ubuntu下使用PowerDesigner15(亲测可用)