C/C++函数调用约定(基于X86架构下)
__cdecl约定
C/C++中缺省调用约定
int add(int a, int b)
{
00D91002 in al,dx
00D91003 push ecx int c = a + b;
00D91004 mov eax,dword ptr [a]
00D91007 add eax,dword ptr [b]
00D9100A mov dword ptr [c],eax return c;
00D9100D mov eax,dword ptr [c]
}int main()
{
00D91020 push ebp
00D91021 mov ebp,esp add(3, 4);
00D91023 push 4
00D91025 push 3
00D91027 call add (0D91000h)
00D9102C add esp,8 //恢复栈平衡
}
参数从右到左入栈,在函数外恢复栈平衡,返回值在EAX中
由于由调用者平衡栈,所以允许可变参数函数存在
__stdcall约定
常见于WINAPI中
int __stdcall add(int a, int b)
{
00641002 in al,dx
00641003 push ecx int c = a + b;
00641004 mov eax,dword ptr [a]
00641007 add eax,dword ptr [b]
0064100A mov dword ptr [c],eax return c;
0064100D mov eax,dword ptr [c]
}
00641010 mov esp,ebp
00641012 pop ebp
00641013 ret 8//恢复栈平衡int main()
{
00641020 push ebp
00641021 mov ebp,esp add(3, 4);
00641023 push 4
00641025 push 3
00641027 call add (0641000h)
}
参数入栈方式与__cdecl相同;不同于__cdecl,由函数恢复栈平衡;返回值在eax中
__thiscall约定
C++中用于调用成员函数
class Math
{
public:int add(int a, int b){
002E1002 in al,dx
002E1003 sub esp,8
002E1006 mov dword ptr [ebp-8],ecx int c = a + b;
002E1009 mov eax,dword ptr [ebp+8]
002E100C add eax,dword ptr [ebp+0Ch]
002E100F mov dword ptr [ebp-4],eax return c;
002E1012 mov eax,dword ptr [ebp-4] }
002E1015 mov esp,ebp
002E1017 pop ebp
002E1018 ret 8 int main()
{
002E1020 push ebp
002E1021 mov ebp,esp
002E1023 sub esp,8
002E1026 mov eax,dword ptr ds:[002E3000h]
002E102B xor eax,ebp
002E102D mov dword ptr [ebp-4],eax Math math;math.add(3, 4);
002E1030 push 4
002E1032 push 3
002E1034 lea ecx,[ebp-5]
002E1037 call 002E1000
}
与__stdcall相同,由函数自身恢复栈平衡;
从右向左将参数传入栈中,ecx保存类的指针
__fastcall约定
调用成员函数时
class Math
{
public:int __fastcall add(int a, int b){
00501002 in al,dx
00501003 sub esp,0Ch
00501006 mov dword ptr [ebp-4],edx
00501009 mov dword ptr [ebp-0Ch],ecx int c = a + b;
0050100C mov eax,dword ptr [ebp-4]
0050100F add eax,dword ptr [ebp+8]
00501012 mov dword ptr [ebp-8],eax return c;
00501015 mov eax,dword ptr [ebp-8] }
00501018 mov esp,ebp
0050101A pop ebp
0050101B ret 4int main()
{
00501020 push ebp
00501021 mov ebp,esp
00501023 sub esp,8
00501026 mov eax,dword ptr ds:[00503000h]
0050102B xor eax,ebp
0050102D mov dword ptr [ebp-4],eax Math math;math.add(3, 4);
00501030 push 4
00501032 mov edx,3
00501037 lea ecx,[ebp-5]
0050103A call 00501000
}
调用普通函数时
int __fastcall add(int a, int b){
00391002 in al,dx
00391003 sub esp,0Ch
00391006 mov dword ptr [ebp-8],edx
00391009 mov dword ptr [ebp-4],ecx int c = a + b;
0039100C mov eax,dword ptr [ebp-4]
0039100F add eax,dword ptr [ebp-8]
00391012 mov dword ptr [ebp-0Ch],eax return c;
00391015 mov eax,dword ptr [ebp-0Ch] }
00391018 mov esp,ebp
0039101A pop ebp
0039101B retint main()
{
00391020 push ebp
00391021 mov ebp,esp add(3, 4);
00391023 mov edx,4
00391028 mov ecx,3
0039102D call 00391000
}
优先使用寄存器ECX和EDX传送前两个DWORD或更小参数,节省push操作,因此速度较快
其他约定
___naked
naked是一个很少见的调用约定,一般不建议使用。编译器不会给这种函数增加初始化和清理代码,更特殊的是你不能用return返回返回值,只能用插入汇编返回结果,此调用约定必须跟_declspec同时使用。例如定义一个求和程序,如:_declspec (naked) int add(int a,int b) ;
___pascal
这是pascal语言的调用约定,跟_stdcall一样,参数按照从右至左的方式入栈,函数自身清理堆栈,返回值在EAX中。VS 中已经废弃了这种调用方式.
C/C++函数调用约定(基于X86架构下)相关推荐
- x86架构下的安卓虚拟化
目录 一 国内现状... 1 二 实现方案... 1 三 测试方案... 2 四 技术难点... 4 一 国内现状 国内云手游解决方案大致分为三种: 1.真实手机板卡机器插卡方案 2.使用ARM服务器 ...
- 【参赛作品14】Windows安装华为openGauss数据库——openGauss基于x86架构openEuler虚拟机的编译以及JDBC的连接
1.Hype-V虚拟机安装openEuler 虚拟机平台有很多,像vmware.Hype-V.VirtualBox等等,考虑到与wsl2的兼容,这里选用Hype-V来安装x86架构的openEuler ...
- 解答:x86架构下,页面大小为什么是4K?
前提:32位逻辑地址空间的计算机系统,三级页表,每个页中每个条目占4Byte,即32位的数据 以上前提是目前x86架构32位系统的真实情况 设:页大小为X(byte) 则:X/4就是每个页中可以存取的 ...
- 基于istio架构下的路径重定向
记录一次在istio架构下的路径拦截重定向做法 目的 实现 总结 目的 想要对特定的URI路径进行拦截重新转发到新的路径下面 实现 istio提供了两种最基本的做法:HTTPRewrite和HTTPR ...
- 卅年史诗!地球上出现过的CPU完全收藏 - (26-28) x86架构下的其它CPU巨鳄 Cyrix,NexGen,IDT/Transmeta(组图)
●Cyrix CPU介绍 突然想起来,X86架构的CPU还有Cyrix公司啊!那我们就接着回顾吧. M1 M1 ,背面 100MHz的M1 100MHz的M1,背面 还是M1,不过公司名称换了 换了名 ...
- x86架构下,页面大小为什么是4K?
前提:32位逻辑空间的计算机OS,两级页表,每个页中每个条目占4bytes,即32位的数据 以上前提是目前X86架构的32为系统的真实情况: 设页大小为X(byte),则X/4为每个页可以存取的条目的 ...
- 基于Hadoop架构下的FineBI大数据引擎技术原理
随着各个业务系统的不断增加,以及各业务系统数据量不断激增,业务用户的分析诉求越来越多且变化很快,IT数据支撑方的工作变得越来越复杂. 1.数据来自多个不同的系统,存在需要跨数据源分析,需要对接各种不同 ...
- 如何在x86架构下进行ARM镜像的构建与运行
这篇文章介绍一下使用QEMU进行容器化的构建和执行方式. 目录 QEMU是什么 常见问题的场景 问题再现 事前准备 启动容器并进入 解决方法 结果确认 构建ARM镜像并确认 QEMU是什么 QEMU是 ...
- 基于ARM架构下的PI数据库远程存储
随着信息技术的进步,计算机技术在工厂的控制层和管理层都得到了充分和广泛的应用.而当计算机技术的应用要求进一部深入和提升时,势必要求把生产控制层和管理层连接起来.实时数据库系统能够及时地把控制层 ...
- 计算机系统-x86架构下的寄存器与寻址
一:段的概念 比方说有这样一段汇编程序 .data abc DWORD 666 .code call abcdef 可以肤浅的理解为abc DWORD 666这句代码存在的内存区域,叫做数据段,cal ...
最新文章
- Django详解之models操作
- RHEL/CentOS/Fedora各种源(EPEL、Remi、RPMForge、RPMFusion)配置
- [译] TypeScript:拥有超能力的 JavaScript(下)
- 和华为hr电话面试的反思
- django 上传文件夹_django上传文件
- java.lang.OutOfMemoryError: GC overhead limit exceeded
- [学习笔记] 乱世之神杀疯了 —— K-D tree
- 10大清宿便排毒方法及简单排毒瘦小腹运动
- CSS浏览器兼容性----Hack
- dart开发Android服务,关于android:在Flutter应用中使用由swagger生成的Dart代码生成的Web服务...
- Shell编程: Shell 变量
- JAVA基础知识总结:二十一
- matplotlib 子图超过4个_Python数据分析:用Matplotlib可视化创建套图
- 时间戳转为时间友好显示
- 蓝桥杯2018年第九届C/C++省赛B组第七题-螺旋折线
- 2017-2018-1 20155220 《信息安全系统设计基础》第十四周学习总结
- freeswitch被叫忙处理
- ADS软件仿真的问题
- DNA 8. 癌症的突变异质性及寻找新的癌症驱动基因(MutSigCV)
- idea 光标 快捷键_IDEA快捷键