Из Технического справочного руководства Cortex-A8:
Процессор поддерживает загрузку и хранение невыровненных слов и
полуслова. Процессор делает необходимое количество обращений к памяти
и прозрачно передает соседние байты.
Примечание Доступ к данным, пересекающий границу слова, может увеличить время доступа.
Установка бита A в регистр управления CP15 c1 позволяет выполнить выравнивание
проверка. Когда бит A установлен в 1, доступ к памяти двух типов
генерировать сигнал сброса данных и код состояния ошибки выравнивания:
16-битный доступ без выравнивания по полуслову
32-разрядная загрузка или хранилище, не выровненное по словам
Обнаружение ошибки выравнивания является обязательной функцией генерации адреса.
а не опционально поддерживаемая функция внешней памяти
аппаратное обеспечение управления. См. Справочное руководство по архитектуре для
дополнительная информация о поддержке доступа к выравниваемым данным.
Из ARM ARM, инструкции, которые всегда генерируют ошибку выравнивания, если не выровнены по размеру передачи:
LDREX, STREX, LDREXD, STREXD, LDM, STM, LDRD, RFE, SRS, STRD, SWP, LDC, LDC2, STC, STC2, VLDM, VLDR, VPOP, VPUSH, VSTM, VSTR.
Кроме того, большинство PUSH, POP и VLDx, где: align: указано.
Далее
В реализации, включающей расширения виртуализации,
Нераспределенный доступ к устройству или строго упорядоченной памяти всегда вызывает
Ошибка выравнивания Исключение сброса данных
Как и в связанном вопросе, структуры являются наиболее очевидным способом вызвать «намеченные» не выровненные обращения, но любое повреждение указателя стека или другого указателя переменной также даст тот же результат. В зависимости от того, как настроено ядро, это повлияет, если обычный доступ к одному слову / полуслову просто медленный, или вызовет ошибку.
Если у вас есть доступ к трассировке ETM, вы сможете определить точный доступ. Похоже, что у детали есть ETM / ETB (поэтому не требуется никакого необычного устройства захвата трассировки), но я не представляю, как легко будет заставить инструменты работать с ним.
Что касается кода, который может вызвать это, да, даже memcpy()
может быть проблемой . Поскольку набор инструкций ARM имеет оптимизацию для передачи нескольких регистров (или пар регистров в AA64), оптимизированные библиотечные функции предпочтут «поток» данных, а не выполнять побайтовую загрузку и сохранение. В зависимости от структуры данных и цели компиляции, вполне возможно, что в результате будет получен недопустимый LDM по невыровненным адресам.