>Is the frame pointer guaranteed to be preserved from the time it is set in >.init2 until it is used in main() [...] The *stack pointer* is initialized in .init2 but the *frame pointer* is not. Rather, the frame pointer is set up in the prologue for each function that needs it (i.e. has local storage or takes the address of one or more parameters). The "naked" attribute tells the compiler to omit the function prologue and epilogue which, apparently, also causes the frame pointer setup to be omitted as well. It would be useful to add a caveat to the documentation about using local variables in naked functions.
One way to work around the problem is to create a separate helper function to do the work and then call it from the .init8 function. You'll need to ensure that the helper function is *not* static to avoid having the compiler inline the code. You may also have to adjust the compiler options to prevent the compiler from inlining the code. The output below (resulting from code derived from your example) was obtained using the default call cost and inline size option settings. Don Kinzer --- Example Code --- void id_filter_init8( void ) __attribute__ ((naked)) __attribute__((section(".init8"))); void id_filter_init8( void ) { 98: 07 d0 rcall .+14 ; 0xa8 <bar> 9a: 03 d0 rcall .+6 ; 0xa2 <main> 9c: 2a c0 rjmp .+84 ; 0xf2 <_exit> ... void bar(void) { a8: df 93 push r29 aa: cf 93 push r28 ac: cd b7 in r28, 0x3d ; 61 ae: de b7 in r29, 0x3e ; 62 b0: c0 58 subi r28, 0x80 ; 128 b2: d0 40 sbci r29, 0x00 ; 0 b4: 0f b6 in r0, 0x3f ; 63 b6: f8 94 cli b8: de bf out 0x3e, r29 ; 62 ba: 0f be out 0x3f, r0 ; 63 bc: cd bf out 0x3d, r28 ; 61 be: fe 01 movw r30, r28 c0: 31 96 adiw r30, 0x01 ; 1 uint8_t ff_u8[128U]; /* memset() should really be used here */ for( uint16_t idx_u16 = 0U; idx_u16 < (uint16_t) sizeof( ff_u8 ); idx_u16++) c2: ce 01 movw r24, r28 c4: 8f 57 subi r24, 0x7F ; 127 c6: 9f 4f sbci r25, 0xFF ; 255 { ff_u8[ idx_u16 ] = 0U; c8: 11 92 st Z+, r1 void bar(void) { uint8_t ff_u8[128U]; /* memset() should really be used here */ for( uint16_t idx_u16 = 0U; idx_u16 < (uint16_t) sizeof( ff_u8 ); idx_u16++) ca: e8 17 cp r30, r24 cc: f9 07 cpc r31, r25 ce: e1 f7 brne .-8 ; 0xc8 <bar+0x20> { ff_u8[ idx_u16 ] = 0U; } foo(ff_u8[ val ]); // <-- this is to prevent the code above from being optimized away d0: 80 91 00 01 lds r24, 0x0100 d4: fe 01 movw r30, r28 d6: e8 0f add r30, r24 d8: f1 1d adc r31, r1 da: 81 81 ldd r24, Z+1 ; 0x01 dc: e1 df rcall .-62 ; 0xa0 <foo> } de: c0 58 subi r28, 0x80 ; 128 e0: df 4f sbci r29, 0xFF ; 255 e2: 0f b6 in r0, 0x3f ; 63 e4: f8 94 cli e6: de bf out 0x3e, r29 ; 62 e8: 0f be out 0x3f, r0 ; 63 ea: cd bf out 0x3d, r28 ; 61 ec: cf 91 pop r28 ee: df 91 pop r29 f0: 08 95 ret _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list