分享
 
 
 

编程经验点滴(二)——函数调用时参数压栈顺序的问题

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

编程经验点滴(二)

函数调用时参数压栈顺序的问题

2004-10-24

作 者:杨延庆

E-mail:blankmanATtomDOTcom

出 处:http://blog.csdn.net/blankman/archive/2004/10/24/programing_experience2.aspx

昨天忽然想起来函数压栈顺序的问题,就跟舍友讨论了一下,结果发现在不同的编译器下面出现的结果竟然不一样!于是做了如下分析:

【源程序】

#include <stdio.h>

void print(int a, int b, int c)

{

printf("%d\t%d\t%d\n", a, b, c);

}

int main(void)

{

int p = 0;

print(p++, ++p, p++);

return0;

}

【调用分析】

其实大家应该都知道这个顺序了,我简单粗略的提一下吧。

C 和 C++ 编译器进行函数调用的时候参数压栈的顺序时从右向左的。拿上面的程序来说,首先压栈的参数是最后一个“p++”,压栈的值应该是0,此时 p=1;然后压栈参数的是中间的“++p”,压栈的值是2,此时 p=2;最后压栈的是第一个“p++”,压栈的值应该是 2,此时p=3。

那么,输出结果就应该是“2 2 0”。

【存在问题】

在 Tc、Tc3、GCC 下编译通过,运行结果“2 2 0”;

在 VC.net 下编译通过,运行结果“2 3 0”;

【问题分析】

1、Tc3下从压栈到函数调用阶段的汇编代码:(使用方法 tcc -S filename.cpp)

;

; {

; int p = 0;

;

xor si,si ;将 si 清零,即 p=0

;

; print(p++, ++p, p++);

;

;将最后一个参数压栈,先压栈,后加1

mov ax,si ;ax=0

inc si

push ax

;将中间的参数压栈,先加1,后压栈

inc si

mov ax,si ;ax=2

push ax

;将第一个参数压栈,先压栈,后加1

mov ax,si ;ax=2

inc si

push ax

;调用 print 函数

call near ptr @print$qiii

至此,在 Tc 和 Tc3 下的分析工作完成,结果是“2 2 0”的原因也就很清楚了。

2、Vc.net下从压栈到函数调用阶段的汇编代码:

;

;int p = 0;

;

00411B3E mov dword ptr [p],0;赋初值 0

;

;print(p++, ++p,p++);

;

;操作第三个参数

00411B45 moveax,dword ptr [p];eax= 0 即 p=0

00411B48 mov dword ptr [ebp-0D0h],eax;存放最第三个参数值

00411B4E mov ecx,dword ptr[p];ecx = 0

00411B51 addecx,1;ecx = 1

00411B54mov dword ptr [p],ecx;p =1

;操作第二个参数

00411B57 movedx,dword ptr [p];edx = 1

00411B5Aadd edx,1;edx =2

00411B5D mov dword ptr [p],edx;p = 2

00411B60 mov eax,dword ptr[p];eax = 2

00411B63 movdword ptr [ebp-0D4h],eax;存放第二个参数值

;操作第一个参数

00411B69 mov ecx,dword ptr[p];ecx = 2

00411B6C addecx,1;ecx = 3

00411B6Fmov dword ptr [p],ecx;p =3

;开始压栈

00411B72 mov edx,dword ptr [ebp-0D0h];第三个参数压栈,值为 0

00411B78 push edx

00411B79mov eax,dword ptr [p];第二个参数压栈,值为3

00411B7C push eax

00411B7D mov ecx,dword ptr[ebp-0D4h];第一个参数压栈,值为 2

00411B83 pushecx

;调用 print 函数

00411B84 call print(41100Fh)

00411B89 add esp,0Ch

至此,在 Vc.net 下的分析工作完成,结果是“2 3 0”的原因是压栈的顺序不是标准 C 语言中压栈的顺序,或者说根本就不是顺序,至于为什么这样我也不清楚,如果 .Net 的开发人员注意到了这个问题的话回个贴吧(痴人说梦^_^)。

【建议】

为了你的程序的通用性,不要写那些模棱两可的程序,尽管有很多考试都考这些,我个人不认为把程序写成这样是高手。

上一篇:编程经验点滴(一)——《定义字符串的问题(2004-10-13)》

下一篇:

声明:原创,版权所有,如需转载请注明出处。

http://blog.csdn.net/blankman/archive/2004/10/24/programing_experience2.aspx

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有