• 警惕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;
                  }
           }
           return 0;
    }

      这部分程序使用优化选项(-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

        这时,我们可以看到延时函数被完整的保存下来了。当然实验现象中,我们也可以看出来流水灯的流动。

      说明一点,当程序出现意想不到的情况时,可以通过反汇编来查看问题的原因。

  • 相关阅读:
    AtCoder Beginner Contest 197 F Construct a Palindrome
    AtCoder Beginner Contest 192 F Potion
    AtCoder Beginner Contest 199 E Permutation
    Codeforces1493D GCD of an Array
    Codeforces1499D The Number of Pairs
    Codeforces Global Round 14 E. Phoenix and Computers
    浅谈整除分块
    dsu on tree(树上启发式合并)
    图表绘制文字word编辑线上演示Office LTSC 2021中文激活版
    制作3D人物动画DAZ Studio注册码激活版
  • 原文地址:https://www.cnblogs.com/amanlikethis/p/3367224.html
Copyright © 2020-2023  润新知