- 1、本文档共6页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
C语言函数调用方式的区别
C语言函数调用方式的区别
通常在使用VC进行函数定义时会指定该函数调用方式,诸如:
int __stdcall max(int a, int b)
{
return ab?a:b;
}
int __cdecl min(int a, int b)
{
return ab?a:b;
}
bool __fastcall equal(int a, int b)
{
return a=b?true:false;
}
首先,让我们来分个类,调用方法分为两大类另加一个较特殊的__thiscall.
第一类:__stdcall类 别名:WINAPI,CALLBACK,PASCAL。该类特点是:主调函数负责参数入栈,由函数本身负责栈的恢复。
第二类:__cdecl类 别名:C/C++中默认调用方式,若你定义函数未指定函数调用约定(Calling Conventions),例如在VC6中下面两个函数的调用约定是等价的:
int max(int a, int b)
{
return ab?a:b;
}
int __cdecl min(int a, int b)
{
return ab?a:b;
}
该类调用约定的特点是:由主调函数负责参数入栈,并由主调函数负责线的恢复。
第三类:__thiscall 该类比较特殊,只用于类成员函数调用,你甚至不能强制指定这个函数调用约定。它是由C/C++编译器自动添加的。在C/C++中类成员函数会默认传入一个this指针,对于此,在默入情况下,C/C++中类成员函数通过此类调用约定来指定this指针。
接着介绍一下__thiscall,__thiscall是关于类的一种调用方式。
它与其他调用方式的最大区别是:
__thiscall对每个函数都增加了一个类指针参数
class aa
{
void bb(int cc);
};
实际上bb的函数原形是void bb(aa this, int cc);
__cdecl的调用方式介绍: C和C++缺省调用方式
例子:
void Input( int m,int n);/*相当于void __cdecl Input(int m,int n);*/
以下是相应的汇编代码:
lea eax,[ebp-8] ;取[ebp-8]地址(ebp-8),存到eax
0040106B push eax ;然后压栈
0040106C lea ecx,[ebp-4] ;取[ebp-4]地址(ebp-4),存到ecx
0040106F push ecx ;然后压栈
call @ILT+5(Input) (0040100a);然后调用Input函数
add esp,8 ;恢复栈
从以上调用Input函数的过程可以看出:在调用此函数之前,首先压栈ebp-8,然后压栈ebp-4,然后调用函数Input,最后Input函数调用结束后,利用esp+8恢复栈。由此可见,在C语言调用中默认的函数修饰_cdecl,由主调用函数进行参数压栈并且恢复堆栈。
下面看一下:地址ebp-8和ebp-4是什么? 在VC的VIEW-debug windows-Registers,显示寄存器变量值,然后在选debug windows-Memory,输入ebp-8的值和ebp-4的值(或直接输入ebp-8和-4),看一下这两个地址实际存储的是什么值,实际上是变量n 的地址(ebp-8),m的地址(ebp-4)。
由此可以看出:在主调用函数中进行实参的压栈并且顺序是从右到左。另外,由于实参是相应的变量的引用,也证明实际上引用传递的是变量的地址(类似指针)。
总结:在C或C++语言调用中默认的函数修饰_cdecl,由主调用函数进行参数压栈并且恢复堆栈,实参的压栈顺序是从右到左,最后由主调函数进行堆栈恢复。由于主调用函数管理堆栈,所以可以实现变参函数。另外,命名修饰方法是在函数前加一个下划 线(_)。
_stdcall调用约定介绍:实际上就是PASCAL,CALLBACK,WINAPI
例子:
void WINAPI Input( int m,int n);
看一下相应调用的汇编代码:
lea eax,[ebp-8]
0040106B push eax
0040106C lea ecx,[ebp-4]
0040106F push ecx
call @ILT+5(Input) (0040100a)
从以上调用Input
您可能关注的文档
- 江西省兴国县将军中学2012届高三第二次月考(历史).doc
- 江西省兴国县将军中学2012届高三第二次月考(地理)无答案.doc
- 江西省兴国县将军中学2012届高三第二次月考(政治).doc
- 江西省兴国县将军中学2012届高三第二次月考(数学)(无答案).doc
- 江西省兴国县将军中学2012届高三第二次月考(物理)(无答案).doc
- CIAPE首届中国国际汽车零部件博览会.doc
- 江西省兴国县将军中学2012届高三第二次月考(生物)(无答案).doc
- 江西省兴国县将军中学2012届高三第二次月考(英语).doc
- 江西省兴国县将军中学2012届高三第二次月考(语文)(无答案).doc
- 江西省兴国县将军中学2013-2014学年高一下学期期中考试 化学(兴国班,无答案).doc
文档评论(0)