文档章节

函数调用约定

梦想游戏人
 梦想游戏人
发布于 2015/06/15 20:56
字数 637
阅读 62
收藏 3

..

参数传递顺序

1.从右到左依次入栈:__stdcall,__cdecl,__thiscall,__fastcall

2.从左到右依次入栈:__pascal



主要说明__stdcall __cdecl 区别 

1...__stdcall 被调用的 函数本身负责堆栈平衡

2...__cdecl   调用函数 者负责 该函数的 堆栈平衡


///////**********************    __stdcall    函数本身负责堆栈平衡 *********************////////////////

int  __stdcall a(int v1,int xx)
{
		return 5;
}

int main()
{
	int t=a(5,1);
	return 0;
}

/**/
--- c:\users\hekun\desktop\cppp\cppp\源.cpp -------------------------------------
int  __stdcall a(int v1,int xx)
{
001713C0  push        ebp  
001713C1  mov         ebp,esp  
001713C3  sub         esp,0C0h  
001713C9  push        ebx  
001713CA  push        esi  
001713CB  push        edi  
001713CC  lea         edi,[ebp-0C0h]  
001713D2  mov         ecx,30h  
001713D7  mov         eax,0CCCCCCCCh  
001713DC  rep stos    dword ptr es:[edi]  
		return 5;
001713DE  mov         eax,5  
}
001713E3  pop         edi  
001713E4  pop         esi  
001713E5  pop         ebx  
001713E6  mov         esp,ebp  
001713E8  pop         ebp  
001713E9  ret         8  /*堆栈平衡 函数参数占用8字节*/

--- c:\users\hekun\desktop\cppp\cppp\源.cpp -------------------------------------
int main()
{
00171400  push        ebp  
00171401  mov         ebp,esp  
00171403  sub         esp,0CCh  
00171409  push        ebx  
0017140A  push        esi  
0017140B  push        edi  
0017140C  lea         edi,[ebp-0CCh]  
00171412  mov         ecx,33h  
00171417  mov         eax,0CCCCCCCCh  
0017141C  rep stos    dword ptr es:[edi]  
	int t=a(5,1);
0017141E  push        1  
00171420  push        5  
00171422  call        a (01711E0h)  /* 调用函数a*/
00171427  mov         dword ptr [t],eax  /*返回值位于寄存器eax*/

	return 0;
0017142A  xor         eax,eax  
}
0017142C  pop         edi  
0017142D  pop         esi  
0017142E  pop         ebx  
0017142F  add         esp,0CCh  
00171435  cmp         ebp,esp  
00171437  call        __RTC_CheckEsp (017113Bh)  
0017143C  mov         esp,ebp  
0017143E  pop         ebp  
0017143F  ret





///////**********************    __cdecl    调用函数者 负责堆栈平衡 *********************////////////////

int  __cdecl a(int v1,int xx)
{
		return 5;
}

int main()
{
	int t=a(5,1);

	return 0;
}




/*
反汇编

*/

--- c:\users\hekun\desktop\cppp\cppp\源.cpp -------------------------------------

int  __cdecl a(int v1,int xx)
{
00F313C0  push        ebp  
00F313C1  mov         ebp,esp  
00F313C3  sub         esp,0C0h  
00F313C9  push        ebx  
00F313CA  push        esi  
00F313CB  push        edi  
00F313CC  lea         edi,[ebp-0C0h]  
00F313D2  mov         ecx,30h  
00F313D7  mov         eax,0CCCCCCCCh  
00F313DC  rep stos    dword ptr es:[edi]  
		return 5;
00F313DE  mov         eax,5  
}
00F313E3  pop         edi  
00F313E4  pop         esi  
00F313E5  pop         ebx  
00F313E6  mov         esp,ebp  
00F313E8  pop         ebp  
00F313E9  ret  

--- c:\users\hekun\desktop\cppp\cppp\源.cpp -------------------------------------

int main()
{
00F31400  push        ebp  
00F31401  mov         ebp,esp  
00F31403  sub         esp,0CCh  
00F31409  push        ebx  
00F3140A  push        esi  
00F3140B  push        edi  
00F3140C  lea         edi,[ebp-0CCh]  
00F31412  mov         ecx,33h  
00F31417  mov         eax,0CCCCCCCCh  
00F3141C  rep stos    dword ptr es:[edi]  
	int t=a(5,1);
00F3141E  push        1  
00F31420  push        5  
00F31422  call        a (0F311E5h)  /* 调用函数 a  */
00F31427  add         esp,8     /* 由于是 __cdecl 调用方式 所以调用者 main 负责堆栈平衡,函数a 返回后 立即堆栈平衡(占用8字节)  变参函数只能是这种调用,因为只有调用者才知道 参数实际大小*/
00F3142A  mov         dword ptr [t],eax  

	return 0;
00F3142D  xor         eax,eax  
}
00F3142F  pop         edi  
00F31430  pop         esi  
00F31431  pop         ebx  
00F31432  add         esp,0CCh  
00F31438  cmp         ebp,esp  
00F3143A  call        __RTC_CheckEsp (0F3113Bh)  
00F3143F  mov         esp,ebp  
00F31441  pop         ebp  
00F31442  ret



__fastcall 调用  前参数 最大8字节 一次放入寄存器 ecx和edx  其余参数 放入栈中


© 著作权归作者所有

共有 人打赏支持
梦想游戏人
粉丝 36
博文 437
码字总数 124258
作品 0
成都
私信 提问
WIN32编程必知:__stdcall,__cdecl,__fastcall,thiscall,n

被这些修饰关键字修饰的函数,其参数都是从右向左通过堆栈传递的(fastcall的前面部分由ecx,edx传), 函数调用在返回前要清理堆栈,但由调用者还是被调用者清理不一定。 1、_stdcall是Pascal程...

guoliang
2014/04/03
0
0
_cdecl、_stdcall、_fastcall和_thiscall整理

cdecl、stdcall、fastcall和thiscall整理 1._cdecl是C Declaration的缩写,表示C语言默认的函数调用方法:所有参数 从右到左依次入栈,这些参数由调用者清除,称为手动清栈(由调用者把参数弹...

西昆仑
2011/11/17
0
1
__declspec(dllimport)和__declspec(dllexport)的区别,以及有关c/c++调用约定

DLL可以使用两种方法将公共符号导入到应用程序中或从 DLL 导出函数: 生成 DLL 时使用模块定义 (.DEF) 文件。 在主应用程序的函数定义中使用 declspec(dllimport) 或 declspec(dllexport) 关...

AlphaJay
2010/08/20
0
0
__cdecl __stdcall

1.如果函数func是cdecl(默认调用方式),调用时情况如下 int main() { //参数从右到左压栈 push 4 push 3 push 2 push 1 call func add esp 0x10 //调用者恢复堆栈指针esp,4个参数的大小是0...

ryany
2011/03/21
0
0
带你玩转Visual Studio——调用约定__cdecl、__stdcall和__fastcall

有一定C++开发经验的人一定对"cdecl、stdcall、fastcall"肯定不陌生吧!但你真正理解了吗?是的,我曾在这采了无数个坑,栽了无数个跟头,终于忍无可忍要把它总结一下(虽然我已经有能力解决大...

spencer.luo
2017/12/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

vue 对对象的属性进行修改时,不能渲染页面 vue.$set()

我在vue里的方法里给一个对象添加某个属性时,我console.log出来的是已经更改的object ,但是页面始终没有变化 原因如下: **受现代 JavaScript 的限制 (而且 Object.observe 也已经被废弃),...

Js_Mei
51分钟前
0
0
开始看《Java学习笔记》

虽然书买了很久,但一直没看。这其中也写过一些Java程序,但都是基于IDE的帮助和对C#的理解来写的,感觉不踏实。 林信良的书写得蛮好的,能够帮助打好基础,看得出作者是比较用心的。 第1章概...

max佩恩
昨天
12
0
Redux 三大原则

1.单一数据源 在传统的MVC架构中,我们可以根据需要创建无数个Model,而Model之间可以互相监听、触发事件甚至循环或嵌套触发事件,这些在Redux中都是不被允许的。 因为在Redux的思想里,一个...

wenxingjun
昨天
8
0
跟我学Spring Cloud(Finchley版)-12-微服务容错三板斧

至此,我们已实现服务发现、负载均衡,同时,使用Feign也实现了良好的远程调用——我们的代码是可读、可维护的。理论上,我们现在已经能构建一个不错的分布式应用了,但微服务之间是通过网络...

周立_ITMuch
昨天
4
0
XML

学习目标  能够说出XML的作用  能够编写XML文档声明  能够编写符合语法的XML  能够通过DTD约束编写XML文档  能够通过Schema约束编写XML文档  能够通过Dom4j解析XML文档 第1章 xm...

stars永恒
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部