Вопрос или проблема
Путаница с регистрами CPSR для Aarch64: как их читать и кодировка “Режима процессора ARM”
Я работаю с архитектурой Aarch64. Если я правильно понимаю, CPSR
(или “Регистры состояния программы“) – это регистр состояния, который содержит текущее состояние выполнения ядра ЦП.
Я вижу, что WinDbg отображает два варианта этого регистра: cpsr
и spsr
(последний – это “Сохраненный регистр состояния программы”, или значение cpsr
после возникновения исключения).
Я также могу увидеть кодировку битов N
, Z
, C
, V
в нем.
Но меня несколько смущает кодировка битов M[4:0], bits [4:0]
, или “режим процессора ARM“.
Я вижу, что WinDbg выдает мне эти значения (когда я прерываюсь в режиме ядра на Windows 11):
cpsr: 0x60000044
spsr: 0x60000044
Это означает, что биты M
равны: 0b00100
. Но как это может быть правдой, если согласно документации это неопределенная кодировка?
И маленький дополнительный вопрос на эту тему.
Я попытался считать регистр CPSR
напрямую на ассемблере:
mrs x0, CPSR
Но эта инструкция выдает мне такую ошибку при компиляции:
ошибка A2502: операнд 2: Ожидается постоянное значение
Что я там делаю не так?
Это означает, что биты
M
равны:0b00100
. Но как это может быть правдой, если согласно документации это неопределенная кодировка?
Вы смотрели на неправильную документацию, ваша ссылка относится к ARMv7. Если вы посмотрите на ARMv8 и прокрутите вниз, вы увидите:
M[4], бит [4]
Состояние исполнения. Устанавливается в
0b0
, значение PSTATE.nRW, при возникновении исключения к EL1 из состояния AArch64 и копируется в PSTATE.nRW при выполнении операции возвращения из исключения в EL1.
|M[4]|Значение|
|:-|:-|
|0b0|Состояние исполнения AArch64.|При холодном сбросе это поле сбрасывается в архитектурно НЕИЗВЕСТНОЕ значение.
M[3:0], биты [3:0]
Уровень исключения AArch64 и выбранный указатель стека.
|M[3:0]|Значение|
|:-|:-|
|0b0000|EL0t.|
|0b0100|EL1t.|
|0b0101|EL1h.|
Так что вы просто находитесь в EL1 с SP0.
Но эта инструкция выдает мне такую ошибку при компиляции:
ошибка A2502: операнд 2: Ожидается постоянное значение
Что я там делаю не так?
CPSR
не существует в arm64. Есть PSTATE
, который выполняет почти ту же роль, но это тоже не регистр, это “абстракция информации о состоянии процесса”. Вы можете получить доступ к определенным его частям через регистры, такие как NZCV
, PAN
или DAIF
, но единственный способ получить или установить его целиком – это через SPSR_ELn
и вход/возврат исключения.
Ответ или решение
Ответ на вопрос о регистре CPSR в архитектуре AArch64
Здравствуйте!
Вы правильно понимаете, что регистры CPSR и SPSR имеют важное значение в архитектуре ARM. Они используются для хранения состояния процессора, однако стоит отметить, что в архитектуре AArch64 концепция CPSR (Current Program Status Register) изменена и не соответствует тому, что было в архитектурах ARMv7 и ранее.
В архитектуре AArch64 более актуальным является понятие PSTATE (Process State), который обобщает информацию о состоянии процессов, однако это не отдельный регистр. Чтобы получить доступ к состоянию процессора, используются другие регистры, такие как NZCV (для флагов состояния) и SPSR_ELn (сохранённый регистр статуса программы на уровне исключений).
В вашем вопросе упоминается код 0x60000044
, который содержит информацию о состояниях процессора. Давайте разберём, что означают соответствующие биты:
- Bиты
N
,Z
,C
,V
занимают значимые позиции в регистре. -
Биты
M[4:0]
в AArch64 отражают состояние режима выполнения и уровни исключений. Приведенные вами биты0b00100
можно интерпретировать следующим образом:- Бит 4 указывает на то, что процессор работает в состоянии AArch64.
- Биты 3:0 показывают, что процессор выполняется на уровне исключения EL1 и использует стек SP0.
На данный момент вы могли столкнуться с путаницей, потому что вы, возможно, обращались к документации для более ранних архитектур ARM, таких как ARMv7. В документации для AArch64, начиная с ARMv8, можно увидеть, что:
- Бит 4 =
0b0
означает, что процессор находится в AArch64. - Биты 3:0 =
0b0100
означают, что уровень исключения EL1 активен, и используется SP0.
Вопрос о сборке кода
Отвечая на ваш второй вопрос о том, почему ваша команда mrs x0, CPSR
вызывает ошибку компиляции, важно отметить, что в архитектуре AArch64 команда MRS
действительно не может использоваться для чтения CPSR, потому что CPSR в AArch64 не существует. Вместо этого для получения состояния процессора вы должны работать с SPSR_ELn
из соответствующего уровня исключений.
Если вам необходимо работать с состоянием процессора, попробуйте использовать команды, которые взаимодействуют с SPSR или специфичными регистрами, например, MRS x0, SPSR_EL1
. Также помните, что вы должны находиться в контексте исключений, чтобы получить доступ к регистру SPSR.
Если у вас есть дополнительные вопросы или вы хотите уточнить любую часть, не стесняйтесь обращаться!