Использование инструкции 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 банковские регистры
Доступ к банковским регистрам

Другие вопросы по тегам