ARM не генерирует невыровненное исключение

Вот мой код:

 char data[5]  = {0x1, 0x2, 0x3, 0x4, 0x5 };
 int *ptr = (int *)(data + 1);
 int value = *ptr;

 printf("address of data= %lu\n",data);
 printf("address of data +1 = %lu\n",data+1);

Когда я компилирую с помощью gcc -Wcast-align для ARM, он выдает предупреждение «приведение увеличивает требуемое выравнивание целевого типа».

Но когда я запускаю его на процессоре ARM, он не генерирует исключение неправильного доступа.

printf показал, что данные расположены по адресу, кратному 4, и, следовательно, data+1 является нечетным адресом, который должен генерировать невыровненное исключение.

Я установил для /proc/cpu/alignment значение 3. Не получил никакого сообщения в dmesg.

Почему я не получаю исключение?


person linuxfreak    schedule 18.09.2014    source источник
comment
Что вы делаете, чтобы убедиться, что массив данных выравнивается по адресу, кратному 4? Каков фактический адрес массива данных при проверке во время отладки? Какой ARM-процессор?   -  person Malkocoglu    schedule 18.09.2014
comment
Это Arm версии 7. Позвольте мне отредактировать вопрос, чтобы напечатать адрес данных.   -  person linuxfreak    schedule 18.09.2014
comment
просто потому, что рука (mips и т. д.) исторически не одобряла невыровненные передачи, а ошибки при невыровненных передачах не означает, что вы всегда будете видеть это, вы можете отключить событие, и в зависимости от ядра данные, возвращаемые из невыровненной передачи, являются детерминированными (новые ядра больше похожи на чего ожидает программист). снижение производительности, естественно, так же, как и x86...   -  person old_timer    schedule 18.09.2014


Ответы (2)


Там, где действует невыровненная модель доступа ARMv6+, ядро ​​всегда немного очищает SCTLR.A (обратите внимание на часть if (cpu_is_v6_unaligned())...), поскольку на практике нет особого смысла создавать исключения для вещей, которые будут прекрасно работать на оборудовании. Вы получите исключения только для инструкций, которые полностью недействительны, если они не выровнены, например LDM/STM.

person Notlikethat    schedule 18.09.2014
comment
Легко подтверждается cat /proc/cpu/alignment. Если количество пользователей User не увеличивается со стандартным ядром, значит, этого не происходит. - person artless noise; 18.09.2014

1: Возможно, ядро ​​всегда разрешает невыровненный доступ для типов данных ‹= 32 бита и игнорирует вашу настройку /proc.

2: Вы проверили сгенерированный ассемблерный код? Компилятор, возможно, оптимизировал переменную ptr и просто записал в память 4 байта из &data[1] в &value. Таким образом, вы никогда не сможете получить исключение независимо от настройки. Компилятор ARM сделал это для цели Cortex-M3, когда обнаружил невыровненный доступ!

person Malkocoglu    schedule 18.09.2014
comment
Второй момент справедлив и в другом контексте: все, что может вызвать невыровненный доступ, будет неопределенным поведением в C, поэтому компилятор имеет полное право просто не генерировать какой-либо код, который может это сделать. - person Notlikethat; 20.09.2014