在ARM体系结构中,从异常返回可以通过两种方式完成,我知道(可能还有其他方式)。但主要的逻辑是修改PC,这将使处理器触发进入CPSR中设置的模式。
所以pop {...,pc}会切换到主管说用户 或者mov pc,lr也会这样做。
我的问题是,BX lr会切换吗? 假设我正在处理IRQ并且我调用汇编例程说do_IRQ然后从do_IRQ返回是通过BX LR。这会使我的错误处理程序中的bl do_IRQ之后的代码无关吗?
irq_fault_handler:
push {lr}
push {ro-r12}
mrs r0, spsr
push {r0}
bl do_IRQ
pop {r0}
msr cpsr, r0
pop {r0,-r12}
pop {lr}
subs pc, lr, #4
do_IRQ:
...
BX LR
答案 0 :(得分:4)
由于您使用do_IRQ
而不仅仅是分支调用bl
,因此您已经覆盖了lr
,因此无关紧要。此外,即使你只是做了一个分支,你的堆栈也会搞砸(你推r0-r12但在返回之前从不弹出它们。)
此外,您显示的代码似乎也没有正确地从异常中返回。大多数情况下,当您从异常返回时,您希望恢复程序状态寄存器以及mov pc, lr
不会执行的寄存器,也不会bx lr
。
此外,lr
中包含的地址实际上会被几个单词(它根据异常的类型而有所不同)所抵消,因此您无论如何都不会返回正确的指令。对于IRQ,我相信这是一个字。
从IRQ异常返回的推荐方法是subs pc, lr, #4
指令(当然事先已经弹出所有寄存器)which is special in that it also restores the CPSR。