Что делает .p2align в коде asm?

У меня есть эта директива сборки, называемая .p2align, которая генерируется gcc из источника программы C.

Как я понимаю, выравниваемый доступ быстрее, чем неглавный, а также программа asm не автоматически выравнивает места памяти или оптимизирует доступ к памяти, поэтому вам нужно это сделать.

Я не могу прочитать этот .p2align 4,,15, особенно последнюю часть, 15.

Пропуская тот факт, что, по-видимому, gcc генерирует 2 , вместо 1, как сообщается многими документами; я получаю, что этот фрагмент asm выравнивает память таким образом, что каждое место занимает 2 ^ 4 бит, что означает 16 бит, поэтому я считаю, что справедливо сказать, что WORD имеет длину 16 бит в этом случай.

Теперь, что означает 15? Это несколько бит для чего? Начинается ли подсчет с 0, поэтому "реальная" величина равна 16 вместо 15?

EDIT:

Я просто перевел один и тот же источник C как на 32-битный, так и на 64-разрядный код, память всегда выравнивается точно так же с той же директивой .p2align 4,,15. Почему это?

Ответы

Ответ 1

Директива .p2align документирована здесь.

В первом выражении требуется выравнивание по силе двух байтов. .p2align 4 для выравнивания по 16-байтовой границе. .p2align 5 - 32-байтовая граница и т.д.

Второе выражение - это значение, которое будет использоваться в качестве дополнения. Для x86 лучше оставить это и позволить ассемблеру выбрать, так как существует ряд инструкций, которые эффективны без операций. В некоторых директивах выравнивания вы увидите 0x90, который является инструкцией NOP.

Конечным выражением является максимальное количество байтов для заполнения - если для выравнивания требуется больше, чем это, пропустите директиву. В этом случае - 4,,15 - ничего не делает, поскольку 15 - максимальное количество байтов, необходимое для выравнивания по 16 байт.

Ответ 2

Часть p2 названия директивы возникла из-за того, что газ был, возможно, первоначальной реализацией рекомендации для процессора Intel P-II для обеспечения условного выравнивания кода корпуса контура. Как объясняет Агнер Фог, первоначальная цель состояла в том, чтобы убедиться, что первая команда fetch получает достаточный код для начала декодирования.

Существует также взаимодействие с Loop Stream Detector, которое может не ударить, если есть дополнительные фрагменты строки кэша команд, используемые в верхней и нижней частях цикла. Выравнивание производится условно, чтобы избежать потребления большего объема памяти, чем необходимо, и избегать чрезмерного времени в случае, когда выполняются байты заполнения. gcc делает разные варианты выравнивания, в зависимости от настройки целевой mtune.

Были заданы цели, в которых заданы две директивы выравнивания, например, для безусловного 8-байтового выравнивания и условного 32-байтового выравнивания. Причиной выбора различных шаблонов nop является минимизация времени, затраченного в случае, когда выполняется заполняющий поток (когда выполнение входит в цикл сверху). Например, префиксная команда, которая копирует регистр для себя, может потреблять байты кода быстрее, чем одиночные байты. Это не имеет никакого значения в случае, первоначально упоминавшемся в этой теме. Таким образом, часть путаницы может исходить из этой директивы выравнивания, имеющей функции, которые не имеют отношения к настройке выравнивания данных, хотя эта директива также используется для этой цели.