VS2005过度优化的陷阱(二)

       目前还没有新的发现,先把所有现象再次整理如下,望牛人帮忙指正。

       完整代码:

 1  int _tmain( int argc, _TCHAR* argv[])
 2 {
 3      volatile  PS3C6410_GPIO_REG pGPIO1;   // 注意:与 volatile S3C6410_GPIO_REG* pGPIO1;效果是不同的
 4 
 5     pGPIO1 = (PS3C6410_GPIO_REG)GetVirtual(S3C6410_BASE_REG_PA_GPIO,  sizeof(S3C6410_GPIO_REG));
 6 
 7     pGPIO1->GPBCON =  0x22222222;
 8     printf( " \r\n(%08x) ", pGPIO1->GPBCON);
 9      pGPIO1->GPBCON &=  0xFFFF ;   // 替换该行代码,查看其对应的汇编代码
10     printf( " -->(%08x) ", pGPIO1->GPBCON);
11      return  0;
12 }

      下面逐一替换第9行代码,并查看其对应的汇编代码。

      代码1:pGPIO1->GPBCON &= 0xFFFF;被优化掉了

     pGPIO1->GPBCON &=  0xFFFF ;
00011078  ldr         r3, pGPIO1 
    printf( " \r\n(%08x) ", pGPIO1->GPBCON);
0001107C  ldr         r2, pGPIO1 
00011080  ldr         r0, [pc, # 0x14
00011084  strh        r5, [r3, # 0x22
00011088  ldr         r1, [r2, # 0x20
0001108C  bl           00011498

       代码2:pGPIO1->GPBCON &= 0xFFFF<<16;也被优化掉了

     pGPIO1->GPBCON &=  0xFFFF << 16 ;
00011078  ldr         r3, pGPIO1 
    printf( " \r\n(%08x) ", pGPIO1->GPBCON);
0001107C  ldr         r2, pGPIO1 
00011080  ldr         r0, [pc, # 0x14
00011084  strh        r5, [r3, # 0x20
00011088  ldr         r1, [r2, # 0x20
0001108C  bl           00011498

       代码3:pGPIO1->GPBCON &= ~0xFFFF;还是被优化掉了,与代码2的汇编代码完全一样

     pGPIO1->GPBCON &= ~ 0xFFFF ;
00011078  ldr         r3, pGPIO1 
    printf( " \r\n(%08x) ", pGPIO1->GPBCON);
0001107C  ldr         r2, pGPIO1 
00011080  ldr         r0, [pc, # 0x14
00011084  strh        r5, [r3, # 0x20
00011088  ldr         r1, [r2, # 0x20
0001108C  bl           00011498

       代码4:pGPIO1->GPBCON &= ~(0xFFFF<<16);也未能幸免,与代码1的汇编代码完全一样

     pGPIO1->GPBCON &= ~( 0xFFFF << 16 );
00011078  ldr         r3, pGPIO1 
    printf( " \r\n(%08x) ", pGPIO1->GPBCON);
0001107C  ldr         r2, pGPIO1 
00011080  ldr         r0, [pc, # 0x14
00011084  strh        r5, [r3, # 0x22
00011088  ldr         r1, [r2, # 0x20
0001108C  bl           00011498

       代码5:pGPIO1->GPBCON &= 0xFF;这么写没问题!

     pGPIO1->GPBCON &=  0xFF ;
00011078  ldr         r2, pGPIO1 
    printf( " \r\n(%08x) ", pGPIO1->GPBCON);
0001107C  ldr         r1, pGPIO1 
00011080  ldr         r0, [pc, # 0x1C
00011084  ldr         r3, [r2, # 0x20]! 
00011088   and         r3, r3, # 0xFF 
0001108C  str         r3, [r2] 
00011090  ldr         r1, [r1, # 0x20
00011094  bl          000114A0

       代码6:pGPIO1->GPBCON &= 0xFF<<16;这么写也没问题!难道0xFF就没问题了?

     pGPIO1->GPBCON &=  0xFF << 16 ;
00011078  ldr         r2, pGPIO1 
    printf( " \r\n(%08x) ", pGPIO1->GPBCON);
0001107C  ldr         r1, pGPIO1 
00011080  ldr         r0, [pc, # 0x1C
00011084  ldr         r3, [r2, # 0x20]! 
00011088  and         r3, r3, # 0xFF16 
0001108C  str         r3, [r2] 
00011090  ldr         r1, [r1, # 0x20
00011094  bl          000114A0

       代码7:pGPIO1->GPBCON &= ~0xFF;又不对了!

     pGPIO1->GPBCON &= ~ 0xFF ;
00011078  ldr         r3, pGPIO1 
    printf( " \r\n(%08x) ", pGPIO1->GPBCON);
0001107C  ldr         r2, pGPIO1 
00011080  ldr         r0, [pc, # 0x14
00011084  strb        r5, [r3, # 0x20
00011088  ldr         r1, [r2, # 0x20
0001108C  bl           00011498

       代码8:pGPIO1->GPBCON &= ~(0xFF<<16);也被优化掉了。

     pGPIO1->GPBCON &= ~( 0xFF << 16 );
00011078  ldr         r3, pGPIO1 
    printf( " \r\n(%08x) ", pGPIO1->GPBCON);
0001107C  ldr         r2, pGPIO1 
00011080  ldr         r0, [pc, # 0x14
00011084  strb        r5, [r3, # 0x22
00011088  ldr         r1, [r2, # 0x20
0001108C  bl           00011498

       以上8段代码,仅2段代码正常运行,其余都有问题。已经不是运气的事了,肯定某个地方出了问题,在哪呢?

       项目的C/C++属性配置如下:

/O2 /D  " NDEBUG " /D  " _WIN32_WCE=0x600 " /D  " UNDER_CE " /D  " WINCE " /D  " _CONSOLE " /D  " ARM " /D  " _ARM_ " /D  " _UNICODE " /D  " UNICODE " /FD /EHsc /MT /fp:fast /GR- /Yu " stdafx.h " /Fp " CHSINT SDK For WinCE 6.0 (ARMV4I)\Release/GPIOApp.pch " /Fo " CHSINT SDK For WinCE 6.0 (ARMV4I)\Release/ " /Fd " CHSINT SDK For WinCE 6.0 (ARMV4I)\Release/vc80.pdb " /W3 /nologo /c /Zi /TP

       以上代码,均已“最大化速度”优化。如以“最小化大小”优化,代码如下,也有问题。

    pGPIO1->GPBCON &=  0xFFFF;
000110B0  ldr         r3, [sp] 
    printf( " -->(%08x) ", pGPIO1->GPBCON);
000110B4  ldr         r2, [sp] 
000110B8  mov         r1, # 0 
000110BC  ldr         r0, [pc, # 0x14
000110C0  strh        r1, [r3, # 0x22
000110C4  ldr         r1, [r2, # 0x20
000110C8  bl          000114D4

      若“禁用优化”,对应的代码如下,运行结果也正确。

     pGPIO1->GPBCON &=  0xFFFF ;
000110F8  ldr         r3, [sp] 
000110FC  add         r3, r3, # 0x20 
00011100  str         r3, [sp, # 0xC
00011104  ldr         r3, [sp, # 0xC
00011108  ldr         r2, [r3] 
0001110C  mov         r3, # 0xFF24 
00011110  orr         r3, r3, # 0xFF 
00011114  and         r2, r2, r3 
00011118  ldr         r3, [sp, # 0xC
0001111C  str         r2, [r3] 
    printf( " -->(%08x) ", pGPIO1->GPBCON);
00011120  ldr         r3, [sp] 
00011124  add         r3, r3, # 0x20 
00011128  ldr         r1, [r3] 
0001112C  ldr         r0, [pc, # 0x14
00011130  bl           00011544

       如果全部禁用优化,有点因噎废食的味道,还是希望能找出点原因,以免将来再次触雷。 

你可能感兴趣的:(VS2005过度优化的陷阱(二))