文档章节

函数调用约定

梦想游戏人
 梦想游戏人
发布于 2015/06/15 20:56
字数 637
阅读 61
收藏 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  其余参数 放入栈中


© 著作权归作者所有

共有 人打赏支持
梦想游戏人
粉丝 34
博文 423
码字总数 120460
作品 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
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
带你玩转Visual Studio——调用约定与(动态)库

上一篇文章带你玩转Visual Studio——调用约定cdecl、stdcall和fastcall中已经讲述了cdecl、stdcall和fastcall几种调用约定的主要区别。这一章将进一步深入了解不同调用约定对编译后函数修饰...

spencer.luo
2017/12/25
0
0
__declspec(dllimport)和__declspec(dllexport)的区别,以及有关c/c++调用约定

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

AlphaJay
2010/08/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Mac OS X下Maven的安装与配置

Mac OS X 安装Maven: 下载 Maven, 并解压到某个目录。例如/Users/robbie/apache-maven-3.3.3 打开Terminal,输入以下命令,设置Maven classpath $ vi ~/.bash_profile 添加下列两行代码,之后...

TonyStarkSir
今天
3
0
关于编程,你的练习是不是有效的?

最近由于工作及Solution项目的影响,我在重新学习DDD和领域建模的一些知识。然后,我突然就想到了这个问题,以及我是怎么做的? 对于我来说,提升技能的项目会有四种: 纯兴趣驱动的项目。即...

问题终结者
今天
3
0
打开eclipse出现an error has occurred see the log file

解决方法: 1,打开eclipse安装目录下的eclipse.ini文件; 2,打开的文本文件最后添加一行 --add-modules=ALL-SYSTEM 3,保存重新打开Eclipse。...

任梁荣
昨天
4
0
搞定Northwind示例数据库,无论哪个版本的SQLServer都受用

Northwind数据库 从这里可以找到突破口: http://social.msdn.microsoft.com/Forums/zh-CN/Vsexpressvb/thread/8490a1c6-9018-40c9-aafb-df9f79d29cde 下面是MSDN: http://msdn2.microsoft......

QQZZFT
昨天
1
0
mysql主从同步,安装配置操作

准备 两台mysql服务,我这里准备了如下: 主库:192.168.176.128 从库:192.168.176.131 如何在Linux上安装mysql服务,请看https://blog.csdn.net/qq_18860653/article/details/80250499 操作...

小致dad
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部