菜鸟问题:_stdcall、__stdcall的问题 _stdcall 是不是标准调用的意思? ECX是一个寄存器吧!不太清楚。关注! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 对于函数: func(arg1, arg2)__stdcall调用的伪汇编代码是这样的: push arg1 push arg2 call func__cdecl调用的伪汇编代码是这样的: push arg2 push arg1 call func add ebp, sizeof(arg1)+sizeof(arg2)可以看出,__stdcall方式清除堆栈的工作是由函数func完成的,调用时不需要管栈恢复的问题。而__cdecl方式需要调add ebp, sizeof(arg1)+sizeof(arg2)来恢复栈框架。 __cdecl方式的优点是可以支持不定个数参数,而__stdcall不行(既然参数不定,func就不知道如何清栈)。而且__cdecl方式比较稳定,不会因为函数声明出错导致栈混乱(这是一个很严重的错误,直接导致程序无法继续运行)。其缺点是产生的代码长,每次调用后都需要一个清栈动作。__fastcall方式则尽可能的向寄存器保存函数参数,这当然比在内存中快。ecx是计数寄存器。被__fastcall调用方式用来传递第一个参数(arg1)。上面的ebp也是寄存器,是栈的基指针。 我以前在www.smiling.com上的电子小组问过这个问题 这是holylaker的回答:_stdcall由被调用的函数负责清除调用堆栈。 _cdecl是C/C++函数的缺省调用方式,这种调用方式下由调用者负责清除堆栈。 由于每个_cdecl函数的地方都要生成一段清除堆栈的代码,所以使用_cdecl的函数生成的代码要比_stdcall大。但是,_cdecl有一个好处就是可以实现可变参数表的函数调用,就象printf(const char*, ...)那样。因为具有可变参数表的函数不知道调用的时候到底有多少个参数,所以它无法正确清除堆栈,因此只能使用_cdecl方式,由调用者在函数返回时来进行堆栈的清除工作。 ◇◆◇ 我来散20分,第10个人进来后结贴 ◇◆◇ VC中ADO类的继承问题 读文件,怎么总是反回0啊 软件发布 fp = fopen("e:\\log.txt", "r")到地哪里错了? 急!!高手指教!简单问题! VJProgrammer提供汇编教程的下载地址及说明 为什么我的RichEdit不能接收回车. 有关程序调试的问题 MFC,CListctrl自绘,png图像无法相互覆盖 关于VC的提示问题? 如何在VC中调用ORACLE的存储过程?
__stdcall调用的伪汇编代码是这样的:
push arg1
push arg2
call func
__cdecl调用的伪汇编代码是这样的:
push arg2
push arg1
call func
add ebp, sizeof(arg1)+sizeof(arg2)
可以看出,__stdcall方式清除堆栈的工作是由函数func完成的,调用时不需要管栈恢复的问题。而__cdecl方式需要调add ebp, sizeof(arg1)+sizeof(arg2)来恢复栈框架。
__cdecl方式的优点是可以支持不定个数参数,而__stdcall不行(既然参数不定,func就不知道如何清栈)。而且__cdecl方式比较稳定,不会因为函数声明出错导致栈混乱(这是一个很严重的错误,直接导致程序无法继续运行)。其缺点是产生的代码长,每次调用后都需要一个清栈动作。
__fastcall方式则尽可能的向寄存器保存函数参数,这当然比在内存中快。ecx是计数寄存器。被__fastcall调用方式用来传递第一个参数(arg1)。上面的ebp也是寄存器,是栈的基指针。
_cdecl是C/C++函数的缺省调用方式,这种调用方式下由调用者负责清除堆栈。 由于每个_cdecl函数的地方都要生成一段清除堆栈的代码,所以使用_cdecl的函数生成的代码要比_stdcall大。但是,_cdecl有一个好处就是可以实现可变参数表的函数调用,就象printf(const char*, ...)那样。因为具有可变参数表的函数不知道调用的时候到底有多少个参数,所以它无法正确清除堆栈,因此只能使用_cdecl方式,由调用者在函数返回时来进行堆栈的清除工作。