文档章节

函数调用约定

梦想游戏人
 梦想游戏人
发布于 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  其余参数 放入栈中


© 著作权归作者所有

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

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

spencer.luo
2017/12/25
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

没有更多内容

加载失败,请刷新页面

加载更多

码云项目100,水一发

简单回顾一下: 早期构想最多的,是希望能将PHP一些类和编码分区做得更细,所以很多尝试。但不得不说,PHP的功能过于单一,是的,也许写C/C++扩展,可以解决问题,那我为什么不用C#或者Golan...

曾建凯
今天
3
0
Spring应用学习——AOP

1. AOP 1. AOP:即面向切面编程,采用横向抽取机制,取代了传统的继承体系的重复代码问题,如下图所示,性能监控、日志记录等代码围绕业务逻辑代码,而这部分代码是一个高度重复的代码,也就...

江左煤郎
今天
4
0
eclipse的版本

Eclipse各版本代号一览表 Eclipse的设计思想是:一切皆插件。Eclipse核心很小,其它所有功能都以插件的形式附加于Eclipse核心之上。 Eclipse基本内核包括:图形API(SWT/Jface),Java开发环...

mdoo
今天
3
0
SpringBoot源码:启动过程分析(一)

本文主要分析 SpringBoot 的启动过程。 SpringBoot的版本为:2.1.0 release,最新版本。 一.时序图 还是老套路,先把分析过程的时序图摆出来:时序图-SpringBoot2.10启动分析 二.源码分析 首...

Jacktanger
今天
6
0
小白带你认识netty(二)之netty服务端启动(上)

上一章 中的标准netty启动代码中,ServerBootstrap到底是如何启动的呢?这一章我们来瞅下。 server.group(bossGroup, workGroup);server.channel(NioServerSocketChannel.class).optio...

天空小小
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部