Когда в сборке должны использоваться явные директивы выравнивания? - PullRequest
8 голосов
/ 31 декабря 2010

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

Например, мне было интересно узнать код ассемблера простого оператора C ++. Я знаю, что при определенных обстоятельствах операторы switch основаны на таблицах переходов, как в следующих нескольких строках кода:

    .section    .rodata
    .align 4
    .align 4
.L8:
    .long   .L2
    .long   .L3
    .long   .L4
    .long   .L5
    ...

.align 4 выравнивает следующие данные по следующей 4-байтовой границе, что обеспечивает эффективную выборку этих областей памяти, верно? Я думаю, что это сделано, потому что перед оператором switch могут произойти некоторые вещи, которые вызвали смещение. Но почему на самом деле есть два вызова .align? Существуют ли какие-либо практические правила, когда следует вызывать .align, или это следует делать всякий раз, когда новый блок данных сохраняется в памяти и что-то до этого могло вызвать смещение?

В случае массивов, кажется, что выравнивание выполняется на 32-байтовых границах, как только массив занимает по крайней мере 32 байта. Это более эффективно сделать так или есть другая причина для 32-байтовой границы?

Буду признателен за любые пояснения или подсказки по литературе.

1 Ответ

7 голосов
/ 31 декабря 2010

Существует более одной директивы .align только из-за внутренней компиляции; одного было бы достаточно, а для испускания требуется только одна дополнительная работа.

Что касается выравнивания в целом, это сложная тема, но вот статья для Intel x64, в которой обсуждаются некоторые вопросы, которые вас интересуют:

Другая архитектура может сильно отличаться.

...