警惕arm-linux-gcc编译器优化选项
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){
i = 0;
}
linux下gcc编译的四个步骤}
return0;
}
  这部分程序使⽤优化选项(-O2)编译的,编译后的汇编程序如下所⽰。
0000001c <wait>:
1c:      e12fff1e        bx    lr
00000020 <main>:
20:      e92d4010      stmdb      sp!, {r4, lr}
24:      e3a03b55      mov r3, #87040; 0x15400
28:      e3a04456      mov r4, #1442840576; 0x56000000
2c:      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
3c:      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
4c:      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
5c:      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>
6c:      ebffffea bl    1c <wait>
70:      e2841001      add  r1, r4, #1; 0x1
74:      e1a03284      mov r3, r4, lsl #5
78:      e1e03003      mvn r3, r3
7c:      e3a02456      mov r2, #1442840576; 0x56000000
80:      e3510010      cmp r1, #16; 0x10
84:      e5823014      str    r3, [r2, #20]
88:      e3a04000      mov r4, #0; 0x0
8c:      1afffff4 bne  64 <main+0x44>
90:      eafffff4 b    68 <main+0x48>
94:      00007530      andeq      r7, r0, r0, lsr r5
  可以看到,我们的延时函数完全被优化的没有了,那么我们的延时函数还有什么⽤。实验现象是这个流⽔灯已经完全看不出来流动,⽽是全亮,由于流动的太快⼈眼⽆法识别以⾄于看不出来流动了。
  现在,我把优化选项(-O2)去掉,再来看⼀下反汇编代码。
0000001c <wait>:
1c:      e24dd008      sub  sp, sp, #8; 0x8
20:      e58d0004      str    r0, [sp, #4]
24:      ea000002      b    34 <wait+0x18>
28:      e59d3004      ldr  r3, [sp, #4]
2c:      e2433001      sub  r3, r3, #1; 0x1
30:      e58d3004      str    r3, [sp, #4]
34:      e59d3004      ldr  r3, [sp, #4]
38:      e3530000      cmp r3, #0; 0x0
3c:      1afffff9 bne  28 <wait+0xc>
40:      e28dd008      add  sp, sp, #8; 0x8
44:      e12fff1e        bx    lr
00000048 <main>:
48:      e52de004      str    lr, [sp, #-4]!
4c:      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>
5c:      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>
6c:      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
7c:      e1e03003      mvn r3, r3
80:      e5823000      str    r3, [r2]
84:      e59d3004      ldr  r3, [sp, #4]
88:      e2833001      add  r3, r3, #1; 0x1
8c:      e58d3004      str    r3, [sp, #4]
90:      e59d3004      ldr  r3, [sp, #4]
94:      e3530010      cmp r3, #16; 0x10
98:      1afffff2 bne  68 <main+0x20>
9c:      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
这时,我们可以看到延时函数被完整的保存下来了。当然实验现象中,我们也可以看出来流⽔灯的流动。 说明⼀点,当程序出现意想不到的情况时,可以通过反汇编来查看问题的原因。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。