Согласование данных - это требование к процессору, что означает, что величина выравнивания изменяется от CPU к другому, помните об этом.
Говоря о выравнивании данных стека, например, gcc
поддерживает выравнивание данных с использованием параметра, называемого -mpreferred-stack-boundary=n
, где данные будут выровнены с 2^n
. По умолчанию значение n
равно 4, что делает выравнивание стека 16-байтами.
Это означает, что вы обнаружите, что выделяете 16 байтов в стеке, хотя то, что вы явно выделили, было целым числом.
int main()
{
char ar[6] = {1,2,3,4,5,6};
int x = 10;
int y = 12 + (int) ar[1] + x;
return y;
}
Компиляция кода с GCC на моем CPU производит последующую сборку (проводки только инструкции стека распределение):
subl $32, %esp
Но почему 32? мы выделяем данные, которые точно соответствуют 16 байтам. Ну, есть 8 байт НКУ должны держать сохраненные для leave
и ret
, что делает общую память, необходимой 24
НО, требование выравнивания составляет 16 байт и, таким образом, ССАГПЗА потребности выделить стек-пространство таким образом, что это сделано до 16-байтовых кусков; что 24 байта до 32 решает проблему.
У вас будет достаточно места для ваших переменных, для ret
и leave
, и он состоит из двух 16-байтовых кусков.
Можно заставить компилятор не вставлять ваши структуры данных, хотя, насколько я понимаю, это приведет к потере производительности. – 2013-03-24 17:05:10
@dingrite Некоторые компиляторы позволяют определить определенные атрибуты данных в стеке. Но это исключение, поскольку правила определяются документацией на платформе и делают части приложения несовместимыми со стандартной библиотекой и другим существующим кодом. –
@dingrite Я забыл упомянуть упакованные структуры. Вы можете использовать их, но побочные эффекты и ограничения переносимости могут привести к снижению веса. –