2013-11-26 3 views
3

Так что работа с C в руке-none-eabi-gcc. У меня проблема с указателями, они, похоже, не существуют. Возможно, я передаю компилятор неправильным 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> 

Не должно быть str cmd вокруг 81e4? Чтобы добавить далее, GetGPU_Pointer поступает из файла ассемблера, но есть объявление как таковое.

extern unsigned int * GetGPU_Pointer(unsigned int framebufferAddress); 

Чувство моего кишечника - это что-то абсурдно просто, но я не хватает его.

ответ

7

Вы никогда не изменяете значение gpuPointer, и вы не указали его на volatile. Таким образом, с точки зрения компилятора вы переписываете одну ячейку памяти (*gpuPointer) 768 * 1024 раз, но поскольку вы никогда не используете значение, которое вы записываете в нее, компилятор имеет право оптимизировать, выполнив одну запись в конце цикла ,

+0

Это было! Хотя это также помогло увеличить мой адрес, а также пояснить ниже. Еще раз спасибо! – BenE

4

Добавление ответа RICI (в upvote 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

спасибо, обратите внимание, что ваш вопрос/проблема не была конкретной рукой. Будет иметь ту же проблему при компиляции/оптимизации для любой из целей. –

Смежные вопросы