2013-11-26 46 views
3

因此,在arm-none-eabi-gcc中使用C。我一直有一個指針問題,他們似乎並不存在。也許我將錯誤的cmds傳遞給編譯器。arm-none-eabi-gcc C指針

這裏是一個例子。

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); 

我的直覺是它的東西荒謬的簡單,但我錯過了它。

回答

7

您永遠不會更改gpuPointer的值,並且您尚未聲明它指向volatile。因此,從編譯器的角度來看,您覆蓋了一個單獨的內存位置(*gpuPointer)768 * 1024次,但由於您從不使用您寫入的值,因此編譯器有權通過在循環結束時進行單次寫入來進行優化。

+0

就是這樣!儘管它也有助於增加我的地址以及下面所述的居住地址。再次感謝! – BenE

4

添加到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; 
    } 

} 

優化到

因爲代碼真的不會做任何事情,除了那一家商店。

現在,如果你要修改指針

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. 

問題是,正如所寫的,你沒有告訴編譯器來更新指針比一次多。因此,在我的第一個例子中,沒有理由甚至沒有實現循環,它可以預先計算答案並將其寫入一次。爲了強制編譯器實現循環並多次寫入指針,您需要將其變爲易失性和/或修改它,取決於您真正需要做什麼。

+0

真棒謝謝,我完全錯過了。附註請感謝您幫助我們嘗試進入ARM世界的人所做的一切。我已經從你的幾個例子中學到了很多東西,並會努力向前付款。 – BenE

+0

謝謝,請注意,您的問題不是武器的具體情況。編譯/優化任何目標時會遇到同樣的問題。 –