为啥arm-linux-gcc进入IRQ模式时只保留r0-r4
Posted
技术标签:
【中文标题】为啥arm-linux-gcc进入IRQ模式时只保留r0-r4【英文标题】:Why does arm-linux-gcc only reserve r0-r4 when entering IRQ mode为什么arm-linux-gcc进入IRQ模式时只保留r0-r4 【发布时间】:2014-10-13 14:54:56 【问题描述】:我使用的是基于 ARM cortex-A8 的 S5PV210
当我像这样声明一个中断例程时:
void isr_routine(void) __attribute__ ((interrupt ("IRQ")));
然后像这样编译
arm-linux-gcc -c -march=armv7-a -fpie -fno-builtin $< -o $@
我知道 gcc 会通过推送一些寄存器为我切换上下文。在我知道这一点之前,我是手动完成的。所以我很好奇 gcc 是如何做到的。 反汇编后发现如下代码
PUSH r0-r4,r11,r12,lr
这违背了我关于如何切换上下文的概念。 在ARM cortex-A8官方文档中,明确r0-r12由用户模式和IRQ模式共享。但是用户模式下的lr独立于IRQ模式。所以,我曾经像这样切换上下文
PUSH r0-r12
可以吗?为什么 gcc 推送 lr 注册,为什么不推送 r5-r10 rigsters?
【问题讨论】:
【参考方案1】:r4-r11 作为 ARM ABI 的一部分在函数调用中保留,因此中断例程不需要保存它们,除非函数本身要破坏它们。如果中断例程调用的另一个函数想要修改这些寄存器,它已经有义务将它们作为正常 ABI 的一部分保存和恢复。看来这一套里面,编译器只想用r4和r11(r5-r10都没用)。
虽然不具权威性,但***的文章很容易阅读并且可能会有所帮助:http://en.wikipedia.org/wiki/Calling_convention#ARM
【讨论】:
【参考方案2】:r5-r10 是 ARM 中的被调用者保存寄存器,因此如果在 isr_routine 中使用它们,gcc 会推送它们。如果不使用它们(如果可能,它会尽量不使用它们),它不会费心保存/恢复它们的值,因为这是不必要的。我猜你的 isr_routine 很简单,不需要它们(一切都适合 r0-r4 或 r11-r12)
【讨论】:
以上是关于为啥arm-linux-gcc进入IRQ模式时只保留r0-r4的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在使用 ThreeJS 和 VueJS 时只看到黑色背景?