http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55757
Joey Ye <joey.ye at arm dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |joey.ye at arm dot com --- Comment #4 from Joey Ye <joey.ye at arm dot com> 2012-12-21 03:23:07 UTC --- > An interrupt handler function (void something(void)), but without attribute, > doing something inside (posts a FreeRTOS semaphore, calls vPortYieldFromISR() > if it's needed) actually saves a lot of registers on entry: > 23b4: b507 push {r0, r1, r2, lr} Pushing of scratch registers can be used to 1. align stack, which Richard has explained 2. allocate stack frame, as a code size optimization of sub sp, #x Explain with following example: extern void bar(int *, int *); void foo() { int a, b; bar(&a, &b); } Built with -Os -mcpu=cortex-m3: push {r0, r1, r2, lr} Here, pushing of r0 and r1 allocates a 8-byte frame for local variables. Pushing of r2 is to make sp aligned to 8 bytes together with pushing lr. Values of r0-r2 pushed to stack don't really matter. But built with -O2: push {lr} sub sp, sp, #12 Former is better on code size, latter wins on performance. Hopefully this explains everything.