这算是VC6.0编译器的一个Bug么?

首先看看上面这段C代码,按照C语言的运算符优先级规则,这个程序的运行结果应该是18(首先执行完小括号里的三个++a,这时a就为6,然后在执行加法运算,3个a相加自然等于18)。

 

可是我在VC6.0下编译这段程序时,如果编译为Debug版,则输出结果为16,如果编译为Release版本,则输出结果为18。

为什么Debug版本的结果会是16呢???怎么想也不应该是16啊。于是自然就想到了看看这段程序对应Debug版的汇编代码吧,看看VC的编译器究竟把这段代码编译成什么样子了。为了简单起见,我只分析子函数bug()。

 

int a=3,b;
b=(++a)+(++a)+(++a);

 

以上这两行代码在VC的Debug版本下对应的汇编代码为:
0040102F 8B 45 FC             mov         eax,dword ptr [ebp-4]
00401032 83 C0 01             add         eax,1
00401035 89 45 FC             mov         dword ptr [ebp-4],eax
00401038 8B 4D FC             mov         ecx,dword ptr [ebp-4]
0040103B 83 C1 01             add         ecx,1
0040103E 89 4D FC             mov         dword ptr [ebp-4],ecx
00401041 8B 55 FC             mov         edx,dword ptr [ebp-4]
00401044 03 55 FC             add         edx,dword ptr [ebp-4]
00401047 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040104A 83 C0 01             add         eax,1
0040104D 89 45 FC             mov         dword ptr [ebp-4],eax
00401050 03 55 FC             add         edx,dword ptr [ebp-4]
00401053 89 55 F8             mov         dword ptr [ebp-8],edx

 

上面这段汇编代码的意思,相信只要懂得汇编的朋友都可以很容易看懂,不过为了照顾一下大众,我还是简单说明一下吧,根据变量定义的位置可以知道,ebp-4就是变量a的地址,ebp-8就是变量b的地址,于是以上代码可以简化为:
mov eax,a
add eax,1
mov a,eax
//此时a=4
mov ecx,a
add ecx,1
mov a,ecx
//此时a=5
mov edx,a
add edx,a
//此时edx=10
mov eax,a
add eax,1
mov a,eax
//此时a=6
add edx,a
mov b,edx
//此时b=16

 

所以,Debug版本的最后输出结果自然就是16,但我认为这是一个错误的结果。但是为什么Release版的又能返回我认为正确的结果18呢?于是,随后我又用OD对Release版的程序进行了逆向分析,大家看图:

逆向分析截图

这个结果让我感到很意外,在Release版中,子函数bug()居然被优化成了直接返回结果:0x12(十进制就是18)。

 

至于其中为什么会优化成那样的原因我可就不知道了,这要去问问微软那些开发这个VC编译器(这里顺便提一下:VC6.0自带的 C/C++编译器的版本为:Version 12.00.8804)的工程师了,呵呵。当然也可以通过逆向分析这个VC编译器,从而找到答案,不过本人能力有限,目前还很难办到,若哪位大牛路过,还请不吝赐教。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值