ARM Cortex-M内核文档说,执行了异常输入堆栈分帧。这会导致寄存器R0,R1,R2,R3,R12,LR,PC,xPSR被压入当前堆栈。 我的问题是为什么这种方式只推送这些寄存器而不是所有的上下文?例如,如果某些数据在R5寄存器中,则在异常处理程序使用该寄存器的情况下将被覆盖。
异常处理程序的编译函数本身会推送一些寄存器(以及其他常规函数,因为异常处理函数没有区别),但经过很多调试后,我发现事实并非总是如此,因为寄存器的不同变化被推动然后恢复。ARM Cortex-M异常输入和堆栈分帧
3
A
回答
8
为什么这种方式只推送这些寄存器而不是所有的 上下文?
提高中断响应时间。更少的堆栈操作意味着处理程序可以更快地启动。
例如,如果某些数据在R5寄存器中,在异常处理程序使用该寄存器的情况下,将被覆盖 。
然后处理程序的责任是保存R5。
编译异常处理程序本身的函数把一些寄存器 (以及所有其他常规功能,因为异常处理程序 功能是没有区别)
这是故意的。被调用的函数必须保存与中断处理程序(R4-R11和SP)相同的一组寄存器。所以,如果一个正常的函数想要使用R5,它必须保存在某个地方并稍后恢复(详情请参阅Procedure Call Standard for the ARM® Architecture)。这样,编译器可以像处理普通函数一样处理中断函数。
它并不总是这种情况,因为寄存器的不同变化是 被推动然后恢复。
如果编译的函数在不保存和恢复的情况下覆盖R4-R11范围内的寄存器,或者没有正确恢复PC或SP,那么编译器会被中断。
相关问题
- 1. 如何从异常“跳”到堆栈帧?
- 2. 调用堆栈上的异常处理堆栈帧的顺序
- 3. 异常和堆栈跟踪
- 4. 堆栈帧和堆栈指针
- 5. 堆栈帧内存分配
- 6. Java异常处理和堆栈跟踪
- 7. 堆栈展开异常C++
- 8. 堆栈溢出异常
- 9. 异常堆栈跟踪
- 10. 堆栈溢出异常
- 11. 空引用异常堆栈
- 12. 堆栈空间异常
- 13. ARM AArch64堆栈管理
- 14. Zend_Search_Lucene“在第0行未知堆栈帧时抛出的异常”
- 15. 在异常情况下获取函数的堆栈帧
- 16. C++禁用堆栈帧下面的异常
- 17. 获取堆栈帧
- 18. ARM M0 +引导程序重定位后的异常堆栈指针
- 19. C#WPF Window.ShowDialog堆栈溢出异常
- 20. 异常(堆栈跟踪)在一行
- 21. 异常向上传播调用堆栈
- 22. 异常java.lang.StackOverflowError:堆栈大小8MB
- 23. 之前堆栈溢出异常的main()
- 24. Control.EndInvoke重置调用堆栈异常
- 25. 链式异常堆栈示例
- 26. 避免堆栈溢出异常
- 27. ASM ByteCode - 异常的堆栈跟踪
- 28. Xcode异常停止在堆栈顶部
- 29. DllIImport函数抛出堆栈异常
- 30. 调试C# - 堆栈溢出异常?
我希望在这个论坛中的所有答案都是这样的。清晰,简单,带有参考。谢谢! –