I'm using S5PV210 which is based on ARM cortex-A8
When i declare a interrupt routine like this:
void isr_routine(void) __attribute__ ((interrupt ("IRQ")));
And compile like this
arm-linux-gcc -c -march=armv7-a -fpie -fno-builtin $< -o $@
I know that gcc will switch context for me by push some registers.Before i know this, i did it manually.So i'm curious about how gcc do it. After disassembling, I found codes like below
PUSH {r0-r4,r11,r12,lr}
It goes against my conception about how to switch context. In Arm cortex-A8 official document, it's explicit that r0-r12 is shared by user mode and IRQ mode.However lr in user mode is independent from IRQ mode.So, I used to switch context like this
PUSH {r0-r12}
Is it OK? Why does gcc push lr register and why doesn't gcc push r5-r10 rigsters?
r4-r11 are preserved across function calls as part of the ARM ABI, so the interrupt routine does not need to save them unless the function itself is going to clobber them. If another function the interrupt routine calls wants to modify these registers, it's already obligated to save and restore them as part of the normal ABI. It seems that among this set, the compiler only wanted to use r4 and r11 (r5-r10 are not used).
While non-authoritative, the Wikipedia article is easy to read and may be helpful: http://en.wikipedia.org/wiki/Calling_convention#ARM
r5-r10 are callee save registers in ARM, so gcc will push them if they are used in isr_routine. If they are not used (and it will try not to use them if possible), it won't bother to save/restore their value, because it is unnecessary. I'm guessing that your isr_routine is simple enough that they are not needed (everything fits in r0-r4 or r11-r12)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With