微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么arm-linux-gcc在进入IRQ模式时只保留r0-r4

我正在使用基于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注册,为什么gcc不推r5-r10 rigsters?

解决方法

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐