Использование инструкции arm LDM для передачи данных в регистры пользовательского режима
Я пытаюсь восстановить регистры пользовательского режима из режима svc на чипе cortex-a5 с помощью инструкции LDM. Я сослался на техническое руководство по инструкции LDM, синтаксис которого таков:
LDM{addr_mode}{cond} Rn{!},reglist{^}
"^", если указано (в режиме, отличном от "Пользователь" или "Система"), будет выполнено одно из двух возможных специальных действий:
- Данные передаются в регистры пользовательского режима вместо регистров текущего режима (в случае, когда Reglist не содержит ПК).
- Если Reglist действительно содержит ПК, происходит нормальная передача нескольких регистров, и 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
после выполнения кода возникает исключение при прерывании предварительной выборки, ниже приведена информация о регистре:
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, что означает, что ранее ЦП находился в режиме SVC, значение r0 равно 0x00000010, поэтому после выполнения "movs pc, r3" ЦП перейдет в режим пользователя. Значение CPSR[4:0] равно 0x10, это означает, что ЦП работает в пользовательском режиме, поэтому режим ЦП успешно изменяется. Значение {r7, r8} является правильным, однако {sp, lr} является неправильным.
Может кто-нибудь объяснить, что не так с моим кодом? Заранее спасибо.
1 ответ
Режим SVC имеет отдельный банковский регистр для SP
а также LR
, Ваш код сохраняет SVC (или режим предварительной выборки) SP
а также LR
которые не являются оригинальными регистрами режима пользователя. Там нет необходимости для этих линий,
add lr, sp, #8 // saves user mode stack to lr
push {lr}
...
ldmia r5! {sp, lr}^
Вам нужно только ldmia r5! {sp, lr}^
если вы делаете переключение контекста или у вас есть какие-то нелинейные функции, такие как сигнал. movs pc,lr
вероятно, больше подходит для возврата из режима SVC.
Смотрите также:
ARM банковские регистры
Доступ к банковским регистрам