5

我正在使用基于 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 绑定?

4

2 回答 2

7

r4-r11 作为 ARM ABI 的一部分在函数调用中保留,因此中断例程不需要保存它们,除非函数本身要破坏它们。如果中断例程调用的另一个函数想要修改这些寄存器,则它已经有义务将它们作为正常 ABI 的一部分进行保存和恢复。似乎在这组中,编译器只想使用 r4 和 r11(没有使用 r5-r10)。

虽然不具权威性,但维基百科文章很容易阅读并且可能会有所帮助:http ://en.wikipedia.org/wiki/Calling_convention#ARM

于 2014-10-13T16:09:22.707 回答
3

r5-r10 是 ARM 中的被调用者保存寄存器,所以如果它们在 isr_routine 中使用,gcc 会推送它们。如果不使用它们(如果可能,它会尽量不使用它们),它不会费心保存/恢复它们的值,因为这是不必要的。我猜你的 isr_routine 很简单,不需要它们(一切都适合 r0-r4 或 r11-r12)

于 2014-10-13T16:08:05.613 回答