函数列表的形参与函数内部定义的变量,内存地址请教O(∩_∩)O谢谢 为何函数形参列表内定义的形参与函数内部定义的变量在内存地址上差了8个字节!请看图,谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 cdecl调用约定cdecl调用约定又称为C调用约定,是C语言缺省的调用约定,它的定义语法是:int function (int a ,int b) //不加修饰就是C调用约定int __cdecl function(int a,int b)//明确指出C调用约定在写本文时,出乎我的意料,发现cdecl调用约定的参数压栈顺序是和stdcall是一样的,参数首先由有向左压入堆栈。所不同的是,函数本身不清理堆栈,调用者负责清理堆栈。由于这种变化,C调用约定允许函数的参数的个数是不固定的,这也是C语言的一大特色。对于前面的function函数,使用cdecl后的汇编码变成:调用处push 1push 2call functionadd esp,8 注意:这里调用者在恢复堆栈被调用函数_function处push ebp 保存ebp寄存器,该寄存器将用来保存堆栈的栈顶指针,可以在函数退出时恢复mov ebp,esp 保存堆栈指针mov eax,[ebp + 8H] 堆栈中ebp指向位置之前依次保存有ebp,cs:eip,a,b,ebp +8指向a add eax,[ebp + 0CH] 堆栈中ebp + 12处保存了bmov esp,ebp 恢复esppop ebpret 注意,这里没有修改堆栈。MSDN中说,该修饰自动在函数名前加前导的下划线,因此函数名在符号表中被记录为_function,但是我在编译时似乎没有看到这种变化。由于参数按照从右向左顺序压栈,因此最开始的参数在最接近栈顶的位置,因此当采用不定个数参数时,第一个参数在栈中的位置肯定能知道,只要不定的参数个数能够根据第一个后者后续的明确的参数确定下来,就可以使用不定参数,例如对于CRT中的sprintf函数,定义为:int sprintf(char* buffer,const char* format,...)由于所有的不定参数都可以通过format确定,因此使用不定个数的参数是没有问题的。 先上个release的截图,此时变成4个字节的了~我看看下面回复 其实这个问题和可变参无关;我把调用约定去掉,去掉变参,改为写了个普通的函数来测试,控制台工程,int sum2(int first){ int num = 3; return 0;}发现函数形参列表与函数内部定义的第一个变量之间还是有8个不明字节,再者,我打开(vc6,Project->Setting->C/C++页->Category选Code Generation,会看到Calling convention下拉列表里就有):_cdecl(它选中着),_fastcall,_stdcall。难得:_cdecl约定是VC6默认的?大侠回复的那些个汇编看不懂,能否通俗点说下 VC6默认的调用方式是__cdecl C语言调用约定 哦,恩,记得了。那个大侠caozhy的我都没看懂~ AlphaBlend到底能不能进行逐像素的Alpha混合 使用了OPENCV,MFC无法显示新打开的窗口 VC2005中Win32控制台应用程序结合SQL2005问题 关于打印的问题 我用ui设置了全局变量,想结束线程,发现结束不了 如何判断提供字母中能否组合成单词? VC中的有关绘图的函数哪儿有下载? 关于VC中位段的实际长度问题? 急, 怎样在Xtreme Toolkit的Toolbar上面使用真彩图片? mybole() !!!你是傻B还是怎么着?! CMFCToolBar 怎么设置文字呢 ? MFC DefWindowProc窗口消息响应的问题
cdecl调用约定又称为C调用约定,是C语言缺省的调用约定,它的定义语法是:
int function (int a ,int b) //不加修饰就是C调用约定
int __cdecl function(int a,int b)//明确指出C调用约定在写本文时,出乎我的意料,发现cdecl调用约定的参数压栈顺序是和stdcall是一样的,参数首先由有向左压入堆栈。所不同的是,函数本身不清理堆栈,调用者负责清理堆栈。由于这种变化,C调用约定允许函数的参数的个数是不固定的,这也是C语言的一大特色。对于前面的function函数,使用cdecl后的汇编码变成:调用处
push 1
push 2
call function
add esp,8 注意:这里调用者在恢复堆栈被调用函数_function处
push ebp 保存ebp寄存器,该寄存器将用来保存堆栈的栈顶指针,可以在函数退出
时恢复mov ebp,esp 保存堆栈指针mov eax,[ebp + 8H] 堆栈中ebp指向位置之前依次保存有ebp,cs:eip,a,b,ebp +8指向a add eax,[ebp + 0CH] 堆栈中ebp + 12处保存了b
mov esp,ebp 恢复esp
pop ebp
ret 注意,这里没有修改堆栈。
MSDN中说,该修饰自动在函数名前加前导的下划线,因此函数名在符号表中被记录为_function,但是我在编译时似乎没有看到这种变化。由于参数按照从右向左顺序压栈,因此最开始的参数在最接近栈顶的位置,因此当采用不定个数参数时,第一个参数在栈中的位置肯定能知道,只要不定的参数个数能够根据第一个后者后续的明确的参数确定下来,就可以使用不定参数,例如对于CRT中的sprintf函数,定义为:int sprintf(char* buffer,const char* format,...)由于所有的不定参数都可以通过format确定,因此使用不定个数的参数是没有问题的。
我把调用约定去掉,去掉变参,改为写了个普通的函数来测试,控制台工程,int sum2(int first)
{
int num = 3; return 0;
}发现函数形参列表与函数内部定义的第一个变量之间还是有8个不明字节,
再者,我打开(vc6,Project->Setting->C/C++页->Category选Code Generation,会看到Calling convention下拉列表里就有):_cdecl(它选中着),_fastcall,_stdcall。难得:_cdecl约定是VC6默认的?
大侠回复的那些个汇编看不懂,能否通俗点说下
那个大侠caozhy的我都没看懂~