Что делает .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 является минимизация времени, затраченного в случае, когда выполняется заполняющий поток (когда выполнение входит в цикл сверху). Например, префиксная команда, которая копирует регистр для себя, может потреблять байты кода быстрее, чем одиночные байты. Это не имеет никакого значения в случае, первоначально упоминавшемся в этой теме.
Таким образом, часть путаницы может исходить из этой директивы выравнивания, имеющей функции, которые не имеют отношения к настройке выравнивания данных, хотя эта директива также используется для этой цели.