Note that there are some explanatory texts on larger screens.

plurals
  1. POIs GCC broken when taking the address of an argument on ARM7TDMI?
    text
    copied!<p>My C code snippet takes the address of an argument and stores it in a volatile memory location (preprocessed code):</p> <pre><code>void foo(unsigned int x) { *(volatile unsigned int*)(0x4000000 + 0xd4) = (unsigned int)(&amp;x); } int main() { foo(1); while(1); } </code></pre> <p>I used an SVN version of GCC for compiling this code. At the end of function <code>foo</code> I would expect to have the value <code>1</code> stored in the stack and, at <code>0x40000d4</code>, an address pointing to that value. When I compile without optimizations using the flag <code>-O0</code>, I get the expected ARM7TMDI assembly output (commented for your convenience):</p> <pre><code> .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)" </code></pre> <p>It clearly stores the argument first on the stack and from there stores it at <code>0x40000d4</code>. When I compile with optimizations using <code>-O1</code>, I get something unexpected:</p> <pre><code> .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)" </code></pre> <p>This time the argument is never stored on the stack even though <em>something</em> from the stack is still stored at <code>0x40000d4</code>.</p> <p>Is this just expected/undefined behaviour? Have I done something wrong or have I in fact found a Compiler Bug&trade;?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload