目前还没有新的发现,先把所有现象再次整理如下,望牛人帮忙指正。
完整代码:
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 }
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
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
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
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
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
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, # 0xFF, 16
0001108C str r3, [r2]
00011090 ldr r1, [r1, # 0x20]
00011094 bl 000114A0
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, 16
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
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
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
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, # 0xFF, 24
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
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, # 0xFF, 24
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
如果全部禁用优化,有点因噎废食的味道,还是希望能找出点原因,以免将来再次触雷。