VC6编译器的BUG

来源:互联网 发布:在MAC安装lightroom 6 编辑:程序博客网 时间:2024/04/28 23:01

我是一个每天和VB偶尔和C#打交道,并且梦想着有一天去用C/C++开发实际项目的人,所以很多时候我就会祭出我安装在电脑系统中各种C++编程环境,然后写上几句C/C++代码以安慰我不是一个C/C++程序员的遗憾.然而在今天我碰到了一个奇怪的问题。代码很简单。以致于我写上这个标题时都诚惶诚恐。毕竟对C/C++是 一个不能再菜的菜鸟。

先贴上代码:

#include<stdio.h>
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
int a;
        int idx=0;
int c[sizeof(a)*8-1]={0};
cin>>a;

    while (idx<sizeof(a)*8)  
{
c[idx]=a&1;
a=a>>1;
idx++;

}
idx=0;
while(idx<sizeof(a)*8)
{
cout<<c[idx];
idx++;
}
system("pause");
return 0;
}
第一个while循环成了一个死循环!!!! 然后就单步调式,发现idx就一直在0到31之间循环,到达31后就重新置0了,想学C/C++以前是加了N多群

好问问题啊!但是没得到满意的结果。倒是确定了一点别人VC6下也是同样的问题。我这人有点死磕的精神。再者代码也很简单。

所以想看下反汇编的代码,虽不是很懂汇编,但也只有这一条路了,认真看呗,结果好像还真看出了点东西,下面是汇编的截图

 分析上图汇编代码
00401A69   cmp         dword ptr [ebp-8],20h
这里的20h就是sizeof(a)*8的值十进制32,ptr [ebp-8] 就是idx内存地址,其意思就是32与idx比较
00401A6F   mov         ecx,dword ptr [ebp-4]
ptr [ebp-4] 是a的地址,将a的值赋给ecx
00401A72   and         ecx,1
ecx 与1 进行与操作并放入ecx 也是就是代码中的 a&1
00401A75   mov         edx,dword ptr [ebp-8]
把idx的值放到edx中
00401A78   mov         dword ptr [ebp+edx*4-84h],ecx
这一句就是重点了其意就是把ecx也就是idx的值放入到数组中,我们看下这个数组地址的范围
这里有个84h十进制132,当edx等于31时就是下面这样的
00401A78   mov         dword ptr [ebp+31*4-132],ecx 也就是dword ptr [ebp-8],ecx
ptr [ebp-8] 这个地址是idx的地址,而此时a&1等于也就是ecx等于0,把我的idx赋值为0了
数组元素的地址与idx的地址重合了,难怪如此…………
在vs2008下面,gcc下面没问题,我再贴一下vs2008的反汇编
 #include "stdafx.h"
#include<stdio.h>
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
001513C0  push        ebp  
001513C1  mov         ebp,esp 
001513C3  sub         esp,15Ch 
001513C9  push        ebx  
001513CA  push        esi  
001513CB  push        edi  
001513CC  lea         edi,[ebp-15Ch] 
001513D2  mov         ecx,57h 
001513D7  mov         eax,0CCCCCCCCh 
001513DC  rep stos    dword ptr es:[edi] 
int a;
    int idx=0;
001513DE  mov         dword ptr [idx],0 
int c[sizeof(a)*8-1]={0};
001513E5  mov         dword ptr [c],0 
001513EF  push        78h  
001513F1  push        0    
001513F3  lea         eax,[ebp-94h] 
001513F9  push        eax  
001513FA  call        @ILT+115(_memset) (151078h) 
001513FF  add         esp,0Ch 
cin>>a;
00151402  mov         esi,esp 
00151404  lea         eax,[a] 
00151407  push        eax  
00151408  mov         ecx,dword ptr [__imp_std::cin (15829Ch)] 
0015140E  call        dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (1582A0h)] 
00151414  cmp         esi,esp 
00151416  call        @ILT+330(__RTC_CheckEsp) (15114Fh) 

    while (idx<sizeof(a)*8)  
0015141B  cmp         dword ptr [idx],20h 
0015141F  jae         main+84h (151444h) 
{

 c[idx]=a&1;
00151421  mov         eax,dword ptr [a] 
00151424  and         eax,1 
00151427  mov         ecx,dword ptr [idx] 
0015142A  mov         dword ptr c[ecx*4],eax 
 a=a>>1;
00151431  mov         eax,dword ptr [a] 
00151434  sar         eax,1 
00151436  mov         dword ptr [a],eax 
 idx++;



0 0