Question

In ARM architecture, returning from exception can be done in two ways which I know,(there might be others). But main logic is to modify PC, which will make processor trigger into mode set in CPSR.

So pop {...,pc} would make a switch to say user from supervisor or mov pc,lr would do the same.

My Question is, would a BX lr make the switch ? Assuming I am handling IRQ and I call a assembly routine say do_IRQ and then return from do_IRQ is via BX LR. Would this make the code after bl do_IRQ in my fault handler irrelevant ?

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
Was it helpful?

Solution

It does not make it irrelevant since you called do_IRQ with bl instead of just a branch so you've already overwritten lr. Furthermore, even if you just did a branch, your stack would be messed up (you push r0-r12 but never pop them before returning).

Also, the code you show doesn't seem to return from the exception correctly either. Most of the time, when you return from an exception, you want to restore the program status registers as well as the registers which a mov pc, lr won't do nor will a bx lr.

Furthermore, the address contained in lr will actually be offsetted by a few words (it varies depending on the type of exception) so you're not returning to the correct instruction anyway. For IRQ, I believe it is off by 1 word.

The recommended way to return from an IRQ exception is a subs pc, lr, #4 instruction (after you've pop'd all your registers beforehand of course) which is special in that it also restores the CPSR.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top