I'm trying to restore user mode registers from svc mode on a cortex-a5 chip by using LDM instruction. I referred a technical guide for instruction LDM, the syntax is:
LDM{addr_mode}{cond} Rn{!},reglist{^}
'^' if specified (in a mode other than User or System) means one of two possible special actions will be taken:
- Data is transferred into the User mode registers instead of the current mode registers (in the case where Reglist does not contain the PC).
- If Reglist does contain the PC, the normal multiple register transfer happens and the SPSR is copied into the CPSR. This is used for returning from exception handlers.
Here is the assembly code:
// the CPU is in SVC mode, and is to change to user mode
mrs r0, spsr // copy spsr/cpsr to r0/r1
mrs r1, cpsr
add lr, sp, #8 // saves user mode stack to lr
push {lr}
mov r5, sp
ldmia r5, {r7, r8} // compare {r7,r8} with {sp,lr}
ldmia r5! {sp, lr}^
ldr r3, =0x0 // to generate exception
movs pc, r3 // return to user mode
after the code is executed, pre-fetch abort exception occurs, below is the register info:
r0:0x00000010 r1:0x600000d3 r2:0x02020202 r3:0x03030303
r4:0x03030303 r5:0x800bca2c r6:0x06060606 r7:0x800bca38
r8:0x80018d54 r9:0x09090909 r10:0x10101010 r11:0x11111111
ip:0x12121212 sp:0x800bc964 lr:0x800bca38 pc:0x00000000
CPSR:0x00000010
The value of r1 is 0x600000d3, that means previously the CPU is in SVC mode, the value of r0 is 0x00000010, so after "movs pc, r3" is executed, the CPU will go to user mode. The value of CPSR[4:0] is 0x10, it means CPU is running at user mode, so the CPU mode is changed successfully. The value of {r7, r8} is right, however, {sp, lr} is wrong.
Can anyone explain what's wrong with my code? Thanks in advance.
SVC mode has a separate banked register for SP
and LR
. Your code is saving the SVC (or pre-fetch mode) SP
and LR
which are not the original user mode registers. There is no need for these lines,
add lr, sp, #8 // saves user mode stack to lr
push {lr}
...
ldmia r5! {sp, lr}^
You only need the ldmia r5! {sp, lr}^
if you are doing a context switch or you have some sort of non-linear functionality like a signal. movs pc,lr
is probably more appropriate for a return from SVC mode.
User contributions licensed under CC BY-SA 3.0