arm-linux-gcc的优化选项例如(-O2),可以加速我们的程序,使程序执行效率更高。但是,倘若我们就是需要程序慢一点运行,但是优化却把我们的延时函数优化的没有了的时候,这种优化却不是我们想要的。有时候,我们需要事物差的一面。下边的代码是我的main.c程序。
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
void wait(unsigned long dly)
{
for(; dly > 0; dly--);
}
int main( void)
{
unsigned long i = 0;
GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出
while( 1){
wait( 30000);
GPBDAT = (~(i<< 5)); // 根据i的值,点亮LED1-4
if(++i == 16){
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
void wait(unsigned long dly)
{
for(; dly > 0; dly--);
}
int main( void)
{
unsigned long i = 0;
GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出
while( 1){
wait( 30000);
GPBDAT = (~(i<< 5)); // 根据i的值,点亮LED1-4
if(++i == 16){
i =
0;
}
}
return 0;
}
}
return 0;
}
这部分程序使用优化选项(-O2)编译的,编译后的汇编程序如下所示。
0000001c
<
wait
>:
1 c: e12fff1e bx lr
00000020 <main>:
20: e92d4010 stmdb sp!, {r4, lr}
24: e3a03b55 mov r3, # 87040 ; 0x15400
28: e3a04456 mov r4, # 1442840576 ; 0x56000000
2 c: e59f0060 ldr r0, [pc, # 96] ; 94 <.text+0x94>
30: e5843010 str r3, [r4, # 16]
34: ebfffff8 bl 1c < wait>
38: e3e03000 mvn r3, # 0 ; 0x0
3 c: e59f0050 ldr r0, [pc, # 80] ; 94 <.text+0x94>
40: e5843014 str r3, [r4, # 20]
44: ebfffff4 bl 1c < wait>
48: e3e03020 mvn r3, # 32 ; 0x20
4 c: e5843014 str r3, [r4, # 20]
50: e59f003c ldr r0, [pc, # 60] ; 94 <.text+0x94>
54: ebfffff0 bl 1c < wait>
58: e3e03040 mvn r3, # 64 ; 0x40
5 c: e3a01003 mov r1, # 3 ; 0x3
60: e5843014 str r3, [r4, # 20]
64: e1a04001 mov r4, r1
68: e59f0024 ldr r0, [pc, # 36] ; 94 <.text+0x94>
6 c: ebffffea bl 1c < wait>
70: e2841001 add r1, r4, # 1 ; 0x1
74: e1a03284 mov r3, r4, lsl # 5
78: e1e03003 mvn r3, r3
7 c: e3a02456 mov r2, # 1442840576 ; 0x56000000
80: e3510010 cmp r1, # 16 ; 0x10
84: e5823014 str r3, [r2, # 20]
88: e3a04000 mov r4, # 0 ; 0x0
8 c: 1afffff4 bne 64 <main+0x44>
90: eafffff4 b 68 <main+0x48>
94: 00007530 andeq r7, r0, r0, lsr r5
1 c: e12fff1e bx lr
00000020 <main>:
20: e92d4010 stmdb sp!, {r4, lr}
24: e3a03b55 mov r3, # 87040 ; 0x15400
28: e3a04456 mov r4, # 1442840576 ; 0x56000000
2 c: e59f0060 ldr r0, [pc, # 96] ; 94 <.text+0x94>
30: e5843010 str r3, [r4, # 16]
34: ebfffff8 bl 1c < wait>
38: e3e03000 mvn r3, # 0 ; 0x0
3 c: e59f0050 ldr r0, [pc, # 80] ; 94 <.text+0x94>
40: e5843014 str r3, [r4, # 20]
44: ebfffff4 bl 1c < wait>
48: e3e03020 mvn r3, # 32 ; 0x20
4 c: e5843014 str r3, [r4, # 20]
50: e59f003c ldr r0, [pc, # 60] ; 94 <.text+0x94>
54: ebfffff0 bl 1c < wait>
58: e3e03040 mvn r3, # 64 ; 0x40
5 c: e3a01003 mov r1, # 3 ; 0x3
60: e5843014 str r3, [r4, # 20]
64: e1a04001 mov r4, r1
68: e59f0024 ldr r0, [pc, # 36] ; 94 <.text+0x94>
6 c: ebffffea bl 1c < wait>
70: e2841001 add r1, r4, # 1 ; 0x1
74: e1a03284 mov r3, r4, lsl # 5
78: e1e03003 mvn r3, r3
7 c: e3a02456 mov r2, # 1442840576 ; 0x56000000
80: e3510010 cmp r1, # 16 ; 0x10
84: e5823014 str r3, [r2, # 20]
88: e3a04000 mov r4, # 0 ; 0x0
8 c: 1afffff4 bne 64 <main+0x44>
90: eafffff4 b 68 <main+0x48>
94: 00007530 andeq r7, r0, r0, lsr r5
可以看到,我们的延时函数完全被优化的没有了,那么我们的延时函数还有什么用。实验现象是这个流水灯已经完全看不出来流动,而是全亮,由于流动的太快人眼无法识别以至于看不出来流动了。
现在,我把优化选项(-O2)去掉,再来看一下反汇编代码。
0000001c
<
wait
>:
1 c: e24dd008 sub sp, sp, # 8 ; 0x8
20 : e58d0004 str r0, [sp, # 4 ]
24 : ea000002 b 34 < wait +0x18>
28 : e59d3004 ldr r3, [sp, # 4 ]
2 c: e2433001 sub r3, r3, # 1 ; 0x1
30 : e58d3004 str r3, [sp, # 4 ]
34 : e59d3004 ldr r3, [sp, # 4 ]
38 : e3530000 cmp r3, # 0 ; 0x0
3 c: 1afffff9 bne 28 < wait +0xc>
40 : e28dd008 add sp, sp, # 8 ; 0x8
44 : e12fff1e bx lr
00000048 <main>:
48: e52de004 str lr, [sp, #- 4]!
4 c: e24dd00c sub sp, sp, # 12 ; 0xc
50: e3a03000 mov r3, # 0 ; 0x0
54: e58d3004 str r3, [sp, # 4]
58: e59f2048 ldr r2, [pc, # 72] ; a8 <.text+0xa8>
5 c: e3a03b55 mov r3, # 87040 ; 0x15400
60: e5823000 str r3, [r2]
64: eaffffff b 68 <main+0x20>
68: e59f003c ldr r0, [pc, # 60] ; ac <.text+0xac>
6 c: ebffffea bl 1c < wait>
70: e59f2038 ldr r2, [pc, # 56] ; b0 <.text+0xb0>
74: e59d3004 ldr r3, [sp, # 4]
78: e1a03283 mov r3, r3, lsl # 5
7 c: e1e03003 mvn r3, r3
80: e5823000 str r3, [r2]
84: e59d3004 ldr r3, [sp, # 4]
88: e2833001 add r3, r3, # 1 ; 0x1
8 c: e58d3004 str r3, [sp, # 4]
90: e59d3004 ldr r3, [sp, # 4]
94: e3530010 cmp r3, # 16 ; 0x10
98: 1afffff2 bne 68 <main+0x20>
9 c: e3a03000 mov r3, # 0 ; 0x0
a0: e58d3004 str r3, [sp, # 4]
a4: eaffffef b 68 <main+0x20>
a8: 56000010 undefined
ac: 00007530 andeq r7, r0, r0, lsr r5
b0: 56000014 undefined
1 c: e24dd008 sub sp, sp, # 8 ; 0x8
20 : e58d0004 str r0, [sp, # 4 ]
24 : ea000002 b 34 < wait +0x18>
28 : e59d3004 ldr r3, [sp, # 4 ]
2 c: e2433001 sub r3, r3, # 1 ; 0x1
30 : e58d3004 str r3, [sp, # 4 ]
34 : e59d3004 ldr r3, [sp, # 4 ]
38 : e3530000 cmp r3, # 0 ; 0x0
3 c: 1afffff9 bne 28 < wait +0xc>
40 : e28dd008 add sp, sp, # 8 ; 0x8
44 : e12fff1e bx lr
00000048 <main>:
48: e52de004 str lr, [sp, #- 4]!
4 c: e24dd00c sub sp, sp, # 12 ; 0xc
50: e3a03000 mov r3, # 0 ; 0x0
54: e58d3004 str r3, [sp, # 4]
58: e59f2048 ldr r2, [pc, # 72] ; a8 <.text+0xa8>
5 c: e3a03b55 mov r3, # 87040 ; 0x15400
60: e5823000 str r3, [r2]
64: eaffffff b 68 <main+0x20>
68: e59f003c ldr r0, [pc, # 60] ; ac <.text+0xac>
6 c: ebffffea bl 1c < wait>
70: e59f2038 ldr r2, [pc, # 56] ; b0 <.text+0xb0>
74: e59d3004 ldr r3, [sp, # 4]
78: e1a03283 mov r3, r3, lsl # 5
7 c: e1e03003 mvn r3, r3
80: e5823000 str r3, [r2]
84: e59d3004 ldr r3, [sp, # 4]
88: e2833001 add r3, r3, # 1 ; 0x1
8 c: e58d3004 str r3, [sp, # 4]
90: e59d3004 ldr r3, [sp, # 4]
94: e3530010 cmp r3, # 16 ; 0x10
98: 1afffff2 bne 68 <main+0x20>
9 c: e3a03000 mov r3, # 0 ; 0x0
a0: e58d3004 str r3, [sp, # 4]
a4: eaffffef b 68 <main+0x20>
a8: 56000010 undefined
ac: 00007530 andeq r7, r0, r0, lsr r5
b0: 56000014 undefined
这时,我们可以看到延时函数被完整的保存下来了。当然实验现象中,我们也可以看出来流水灯的流动。
说明一点,当程序出现意想不到的情况时,可以通过反汇编来查看问题的原因。