ARM Cortex M0 / M3/M4: почему ПК всегда четное число в состоянии большого пальца


Насколько я понимаю, процессоры ARM Cortex-M всегда находятся в состоянии большого пальца, что означает:

Состояние большого пальца, обозначаемое счетчиком программы, нечетное (LSB = 1). Ветвление для четного адреса вызовет исключение, так как переключение обратно на Состояние руки не допускается.

Однако, пока я использую процессор CortexM0 и M4, ПК всегда четен . Каждый раз, когда я ветку, ЛР записи ПК+1 и каждый раз, когда я вернусь, ПК дает ЛР-1.

Например, если lr = 0x0000_01D5,

Выполнить

BX lr

Тогда ПК должен быть 0x0000_01D5, тогда как он дает 0x0000_01D4.

Разве это невозможно?

Любой комментарий будет оценен по достоинству.

3 4

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] бит, вы могли бы забыть о битах в ПК - и иметь двойное [или четырехкратное] пространство команд.