1

在 ARM 架构中,可以通过两种我知道的方式从异常返回(可能还有其他方式)。但主要逻辑是修改PC,使处理器触发进入CPSR设置的模式。

所以 pop {...,pc} 会切换到说用户来自 supervisor 或 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
4

1 回答 1

4

它并没有使它无关紧要,因为您调用do_IRQwithbl而不仅仅是一个分支,所以您已经覆盖了lr. 此外,即使你只是做了一个分支,你的堆栈也会被弄乱(你推送 r0-r12 但在返回之前从不弹出它们)。

此外,您显示的代码似乎也没有从异常中正确返回。大多数情况下,当您从异常返回时,您希望恢复程序状态寄存器以及 amov pc, lr不会执行或a 不会执行的寄存器bx lr

此外,其中包含的地址lr实际上会偏移几个字(它取决于异常的类型),因此您无论如何都不会返回到正确的指令。对于 IRQ,我相信它偏离了 1 个字。

从 IRQ 异常返回的推荐方法是一条subs pc, lr, #4指令(当然,在您事先弹出所有寄存器之后),它的特殊之处在于它还恢复了 CPSR

于 2013-09-13T09:44:58.853 回答