【问题标题】:arm-none-eabi-gcc C Pointersarm-none-eabi-gcc C 指针
【发布时间】:2013-11-26 03:13:30
【问题描述】:

所以在 arm-none-eabi-gcc 中使用 C。我一直遇到指针问题,它们似乎不存在。也许我将错误的 cmds 传递给编译器。

这是一个例子。

    unsigned int * gpuPointer = GetGPU_Pointer(framebufferAddress);
    unsigned int color = 16;
    int y = 768;
    int x = 1024;

    while(y >= 0)
    {
        while(x >= 0)
        {
            *gpuPointer = color;
            color = color + 2;
            x--;
        }

        color++;
        y--;
        x = 1024;
    }

以及反汇编程序的输出。

81c8:   ebffffc3    bl  80dc <GetGPU_Pointer>
81cc:   e3a0c010    mov ip, #16 ; 0x10
81d0:   e28c3b02    add r3, ip, #2048   ; 0x800
81d4:   e2833002    add r3, r3, #2  ; 0x2
81d8:   e1a03803    lsl r3, r3, #16
81dc:   e1a01823    lsr r1, r3, #16
81e0:   e1a0300c    mov r3, ip
81e4:   e1a02003    mov r2, r3
81e8:   e2833002    add r3, r3, #2  ; 0x2
81ec:   e1a03803    lsl r3, r3, #16
81f0:   e1a03823    lsr r3, r3, #16
81f4:   e1530001    cmp r3, r1
81f8:   1afffff9    bne 81e4 <setup_framebuffer+0x5c>

81e4 附近不应该有 str cmd 吗?进一步添加 GetGPU_Pointer 来自汇编文件,但有一个声明。

extern unsigned int * GetGPU_Pointer(unsigned int framebufferAddress);

我的直觉是它非常简单,但我想念它。

【问题讨论】:

    标签: c gcc assembly arm disassembly


    【解决方案1】:

    您永远不会更改gpuPointer 的值,也没有声明它指向volatile。因此,从编译器的角度来看,您正在覆盖单个内存位置 (*gpuPointer) 768*1024 次,但是由于您从未使用过写入其中的值,因此编译器有权通过在末尾进行一次写入来进行优化循环。

    【讨论】:

    • 就是这样!虽然它也有助于增加我的地址以及下面所述的 dwelch。再次感谢!
    【解决方案2】:

    添加到 rici 的答案(支持 rici 而不是我)...

    它变得更好,拿走你提供的东西并包装它

    extern unsigned int * GetGPU_Pointer ( unsigned int );
    void fun ( unsigned int framebufferAddress )
    {
        unsigned int * gpuPointer = GetGPU_Pointer(framebufferAddress);
        unsigned int color = 16;
        int y = 768;
        int x = 1024;
    
        while(y >= 0)
        {
            while(x >= 0)
            {
                *gpuPointer = color;
                color = color + 2;
                x--;
            }
    
            color++;
            y--;
            x = 1024;
        }
    
    }
    

    优化到

    00000000 <fun>:
       0:   e92d4008    push    {r3, lr}
       4:   ebfffffe    bl  0 <GetGPU_Pointer>
       8:   e59f3008    ldr r3, [pc, #8]    ; 18 <fun+0x18>
       c:   e5803000    str r3, [r0]
      10:   e8bd4008    pop {r3, lr}
      14:   e12fff1e    bx  lr
      18:   00181110    andseq  r1, r8, r0, lsl r1
    

    因为代码真的只做那个商店。

    现在如果你要修改指针

    while(x >= 0)
    {
        *gpuPointer = color;
        gpuPointer++;
        color = color + 2;
        x--;
    }
    

    然后你会得到你正在寻找的商店

    00000000 <fun>:
       0:   e92d4010    push    {r4, lr}
       4:   ebfffffe    bl  0 <GetGPU_Pointer>
       8:   e59f403c    ldr r4, [pc, #60]   ; 4c <fun+0x4c>
       c:   e1a02000    mov r2, r0
      10:   e3a0c010    mov ip, #16
      14:   e2820a01    add r0, r2, #4096   ; 0x1000
      18:   e2801004    add r1, r0, #4
      1c:   e1a0300c    mov r3, ip
      20:   e4823004    str r3, [r2], #4
      24:   e1520001    cmp r2, r1
      28:   e2833002    add r3, r3, #2
      2c:   1afffffb    bne 20 <fun+0x20>
      30:   e28ccb02    add ip, ip, #2048   ; 0x800
      34:   e28cc003    add ip, ip, #3
      38:   e15c0004    cmp ip, r4
      3c:   e2802004    add r2, r0, #4
      40:   1afffff3    bne 14 <fun+0x14>
      44:   e8bd4010    pop {r4, lr}
      48:   e12fff1e    bx  lr
      4c:   00181113    andseq  r1, r8, r3, lsl r1
    

    或者如果你让它变得易变(然后不必修改它)

    volatile unsigned int * gpuPointer = GetGPU_Pointer(framebufferAddress);
    

    然后

    00000000 <fun>:
       0:   e92d4008    push    {r3, lr}
       4:   ebfffffe    bl  0 <GetGPU_Pointer>
       8:   e59fc02c    ldr ip, [pc, #44]   ; 3c <fun+0x3c>
       c:   e3a03010    mov r3, #16
      10:   e2831b02    add r1, r3, #2048   ; 0x800
      14:   e2812002    add r2, r1, #2
      18:   e5803000    str r3, [r0]
      1c:   e2833002    add r3, r3, #2
      20:   e1530002    cmp r3, r2
      24:   1afffffb    bne 18 <fun+0x18>
      28:   e2813003    add r3, r1, #3
      2c:   e153000c    cmp r3, ip
      30:   1afffff6    bne 10 <fun+0x10>
      34:   e8bd4008    pop {r3, lr}
      38:   e12fff1e    bx  lr
      3c:   00181113    andseq  r1, r8, r3, lsl r1
    

    然后你得到你的商店

    arm-none-eabi-gcc -O2 -c a.c -o a.o
    arm-none-eabi-objdump -D a.o
    arm-none-eabi-gcc (GCC) 4.8.2
    Copyright (C) 2013 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    

    问题是,正如所写,您没有告诉编译器多次更新指针。因此,在我的第一个示例中,它甚至没有理由实现循环,它可以预先计算答案并编写一次。为了强制编译器实现循环并多次写入指针,您需要将其设为 volatile 和/或修改它,这取决于您真正需要做什么。

    【讨论】:

    • 非常感谢,我完全错过了。旁注感谢您为帮助我们尝试进入 ARM 世界的人们所做的一切。我从你的几个例子中学到了很多东西,并会努力付出。
    • 谢谢,请注意,您的问题/问题不是特定于手臂的。为任何目标编译/优化时都会遇到同样的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    • 2020-07-16
    • 2015-12-27
    相关资源
    最近更新 更多