为啥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的主要内容,如果未能解决你的问题,请参考以下文章

ARM的七种工作模式

为啥UITableView回到前面时只显示一半的数据

为啥我的函数在每次页面加载时只运行一次?

为啥我在使用 ThreeJS 和 VueJS 时只看到黑色背景?

为啥 jQuery 在选择器中链接 .attr() 时只选择一个元素?

安装交叉工具链arm-linux-gcc