Когда следует использовать явные директивы выравнивания в сборке?

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

Например, я задавался вопросом о коде сборки простого оператора switch 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-байтовой границы?

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

8
задан Ciro Santilli 新疆改造中心法轮功六四事件 7 November 2015 в 20:38
поделиться