ARM Cortex M0 / M3/M4: почему ПК всегда четное число в состоянии большого пальца
Насколько я понимаю, процессоры ARM Cortex-M всегда находятся в состоянии большого пальца, что означает:
Состояние большого пальца, обозначаемое счетчиком программы, нечетное (LSB = 1). Ветвление для четного адреса вызовет исключение, так как переключение обратно на Состояние руки не допускается.
Однако, пока я использую процессор CortexM0 и M4, ПК всегда четен . Каждый раз, когда я ветку, ЛР записи ПК+1 и каждый раз, когда я вернусь, ПК дает ЛР-1.
Например, если lr = 0x0000_01D5,
Выполнить
BX lr
Тогда ПК должен быть 0x0000_01D5, тогда как он дает 0x0000_01D4.
Разве это невозможно?
Любой комментарий будет оценен по достоинству.
3 ответа:
Из Технического Справочника Cortex-M4 :
2.3.1 счетчик программ
Регистр R15 - это программный счетчик (ПК).Бит [0] всегда равен 0, поэтому инструкции всегда выровнены по границам слова или полуслова.
Чтение из
PC
не должно возвращать нечетный адрес. Однако при записи вPC
LSB значения загружается в T-бит EPSR. Из Общего Руководства Пользователя Устройств Cortex-M3-2.1.3. Ядро регистрыДругими словами, вы можете прочитать даже значения изСостояние большого пальца
Процессор Cortex-M3 поддерживает только выполнение инструкций в Состояние большого пальца. Следующее может очистить бит T до 0:
instructions BLX, BX and POP{PC} restoration from the stacked xPSR value on an exception return bit[0] of the vector value on an exception entry or reset.
Попытка выполнить инструкции, когда бит T равен 0, приводит к ошибка или блокировка. Дополнительную информацию смотрите в разделе блокировка.
PC
, но не можете записать такие значения при нормальных обстоятельствах.
У меня тоже была эта путаница. Lsbit устанавливается для ситуаций, когда адрес будет использоваться BX. Lsbit очищается, когда он входит в сам ПК. Если вы разберете какой-нибудь простой относительный адрес ПК, это продемонстрирует, что происходит.
В то время как существует 4 294 967 296 [2^32] ячеек памяти, фактическая шина данных имеет только 8 бит в ширину.
Для 16-битных инструкций требуется 2 доступа к памяти на загрузку инструкций: именно там начинаются аргументы о "Endian". Каким бы способом вы его ни заказывали, 2 байта считываются с 1-м байтом по адресу, заканчивающемуся на 0.
Если бы шина данных ARM была шириной 16 [или 32] бит, вы могли бы забыть о битах в ПК - и иметь двойное [или четырехкратное] пространство команд.