我正在尝试使用 LDM 指令从 cortex-a5 芯片上的 svc 模式恢复用户模式寄存器。我参考了 LDM 指令的技术指南,语法是:
LDM{addr_mode}{cond} Rn{!},reglist{^}
' ^ ' 如果指定(在用户或系统以外的模式下)表示将采取两种可能的特殊操作之一:
- 数据被传输到用户模式寄存器而不是当前模式寄存器(在 Reglist 不包含 PC 的情况下)。
- 如果 Reglist 确实包含 PC,则会发生正常的多寄存器传输,并将 SPSR 复制到 CPSR 中。这用于从异常处理程序返回。
这是汇编代码:
// 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
代码执行后,发生pre-fetch abort异常,下面是寄存器信息:
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
r1的值为0x600000d3,表示之前CPU处于SVC模式,r0的值为0x00000010,所以执行“movs pc, r3”后,CPU会进入用户态。CPSR[4:0]的值为0x10,表示CPU运行在用户态,因此CPU模式切换成功。{r7, r8} 的值是正确的,但是,{sp, lr} 是错误的。
谁能解释我的代码有什么问题?提前致谢。