http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57873
Bug ID: 57873 Summary: [avr-gcc] Local variable on stack overwritten by call instruction on target AVR Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: schlimmchen at yahoo dot de Created attachment 30491 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=30491&action=edit Sample code to reproduce the bug Have a look at this (real) non-working code snippet: 1 char helper ( char *param ) 2 { 3 return param[0]; 4 } 5 6 int main () { 7 char localNonStaticVar = 0x80; 8 9 helper ( &localNonStaticVar ); 10 11 while ( 1 ) { } 12 13 return 0; 14 } The function "helper" will return the low or high byte (I don't really know which) of the return address in the call of "helper" in "main". Have a look at how "main" is compiled to assembler: avr-gcc -Wall -Wextra -S -mmcu=atmega1284p -O0 main.c -o main.s 35 .type main, @function 36 main: 37 push r28 38 push r29 39 push __zero_reg__ 40 in r28,__SP_L__ 41 in r29,__SP_H__ 42 /* prologue: function */ 43 /* frame size = 1 */ 44 /* stack size = 3 */ 45 .L__stack_usage = 3 46 ldi r24,lo8(-128) 47 std Y+1,r24 48 movw r24,r28 49 adiw r24,1 50 call helper 51 .L4: 52 rjmp .L4 53 .size main, .-main Three registers are pushed onto the stack. Then r28,r29 (special register Y) are assigned the stack pointer address. The value 0x80 is loaded into r24, then stored on top of the stack BUT the stack pointer is NOT changed. In preparation for the call of "helper", the address of this local variable is placed into r24 and r25. Now, the instruction "call" places two bytes (the function return address) on top of the stack, but the stack pointer still points to "__zero_reg__" and the local variable on the stack is overwritten. I guess my explanation is understandable?! See the attached documents for more.