Является GCC нарушается, когда взятие адресааргумента на ARM7TDMI ?

C фрагмент кода берет адрес аргумента и сохраняет его в энергозависимой памяти (предварительно обработанный код):

void foo(unsigned int x) {
    *(volatile unsigned int*)(0x4000000 + 0xd4) = (unsigned int)(&x);
}

int main() {
    foo(1);
    while(1);
}

я использовал SVN-версию GCC для компиляции данного кода. В конце функции foo я ожидаю, чтобы иметь значение 1 хранятся в стеке, а в 0x40000d4, адрес, указывающий на то значение. Когда я копирую без оптимизации, используя флаг -O0, я получил ожидаемого ARM7TMDI Ассамблеи выход (прокомментировал для вашего удобства):

        .align  2
        .global foo
        .type   foo, %function
foo:
        @ Function supports interworking.
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        sub     sp, sp, #8
        str     r0, [sp, #4]     @ 3. Store the argument on the stack
        mov     r3, #67108864
        add     r3, r3, #212
        add     r2, sp, #4       @ 4. Address of the stack variable
        str     r2, [r3, #0]     @ 5. Store the address at 0x40000d4
        add     sp, sp, #8
        bx      lr
        .size   foo, .-foo
        .align  2
        .global main
        .type   main, %function
main:
        @ Function supports interworking.
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        stmfd   sp!, {r4, lr}
        mov     r0, #1           @ 1. Pass the argument in register 0
        bl      foo              @ 2. Call function foo
.L4:
        b       .L4
        .size   main, .-main
        .ident  "GCC: (GNU) 4.4.0 20080820 (experimental)"

Это явно сохраняет аргумент первый стека, и оттуда сохраняет его в 0x40000d4. Когда я компиляции с оптимизацией использования -O1, я получаю нечто неожиданное:

        .align  2
        .global foo
        .type   foo, %function
foo:
        @ Function supports interworking.
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        sub     sp, sp, #8
        mov     r2, #67108864
        add     r3, sp, #4        @ 3. Address of *something* on the stack
        str     r3, [r2, #212]    @ 4. Store the address at 0x40000d4
        add     sp, sp, #8
        bx      lr
        .size   foo, .-foo
        .align  2
        .global main
        .type   main, %function
main:
        @ Function supports interworking.
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        stmfd   sp!, {r4, lr}
        mov     r0, #1           @ 1. Pass the argument in register 0
        bl      foo              @ 2. Call function foo
.L4:
        b       .L4
        .size   main, .-main
        .ident  "GCC: (GNU) 4.4.0 20080820 (experimental)"

на Этот раз аргумент никогда не хранятся в стеке, даже если что-то из стека до сих пор хранятся в 0x40000d4.

это просто ожидаемые/неопределенного поведения? Я сделал что-то неправильно, или я в самом деле нашли Ошибку в Компиляторе

Найдено 11 ответ:

Is GCC broken when taking the address of an argument on ARM7TDMI?

http://stackoverflow.com/questions/28542/is-gcc-broken-when-taking-the-address-of-an-argument-on-arm7tdmi

Посмотреть решение →