Как сгенерировать невыровненное условие доступа и как его обнаружить с помощью gcc? - PullRequest
1 голос
/ 02 мая 2019

В настоящее время я работаю над схемами выделения памяти кучи.Я хочу обнаружить невыровненный доступ без реального оборудования (с использованием gcc).

Во-первых, я использую arm-none-eabi-gcc в качестве компилятора, и моя рабочая станция - Ubuntu 16.04.Я пытался обнаружить не выровненный доступ с помощью этого компилятора.

Я ожидаю, что следующий код действителен с точки зрения выравнивания.

int main ( int argc, char ** argv )
{
    int32_t volatile * const ptr = ( int32_t volatile * ) 0x20000000;
    *ptr = 3;
    *(ptr + 1 ) = 4;
    *(ptr + 2 ) = 5;
    *(ptr + 3 ) = 6;

    return 0;
}

Но я ожидаю, что следующий код недействителен с точки зрениявыравнивание.

int main ( int argc, char** argv )
{
    int32_t volatile * const ptr = ( int32_t volatile * ) 0x20000003;
    *ptr = 3;
    *(ptr + 1 ) = 4;
    *(ptr + 2 ) = 5;
    *(ptr + 3 ) = 6;

    return 0;
}

Я преобразую эти коды C в сборку, используя следующие строки соответственно: arm-none-eabi-gcc -O0 -o main_0.s -S ../main.c, arm-none-eabi-gcc -O0 -o main_3.s -S ../main.c

Когда я сравниваю коды сборки, между этими сборками нет никакой разницыкоды.Также GCC не показывает никаких предупреждений.

Итак, почему эти коды сборки одинаковы?Как я могу создать условие невыровненного доступа?Есть ли способ обнаружить невыровненные условия доступа с помощью GCC?

Спасибо

1 Ответ

1 голос
/ 02 мая 2019

Поскольку в ARM адрес данных всегда является значением регистра (если вы не выполняете относительную загрузку ПК, а в случае ПК младшие биты являются специальными), в сборке нет ничего, что могло бы отличить один загрузка слова и другое.

«Проблема» с невыровненным доступом связана с реализацией архитектуры и взаимодействием процессора с интерфейсами его памяти. Даже если поддерживается невыровненный доступ, он будет работать медленнее, поэтому процессор можно настроить так, чтобы он перехватывал их во время выполнения.

Код, который вы предоставите, будет выполнять не выровненный доступ, но он будет хорошо работать на многих ядрах. Это предполагает, что компилятор не обнаруживает неопределенное поведение (что явно не делает). Я предполагаю, что указатель фактически инициализируется по-другому, когда вы компилируете свой пример.

Вы можете включить или отключить использование функций невыровненного доступа в библиотеках с помощью ключа -munaligned-access см. Описание Keil здесь , но все, что нужно сделать, это определить макрос , не включая проверки во время выполнения или во время компиляции.

В общем, проблемы с выравниванием будут проявляться во время выполнения так же, как и во время компиляции - и для их обнаружения во время выполнения вам понадобится имитатор набора команд (с ловушками, которые могут быть включены).

...