Выравнивание памяти сегодня и 20 лет назад

В известной статье «Разбивая стек для удовольствия и прибыли», ее автор получает функцию C

void function(int a, int b, int c) {
  char buffer1[5];
  char buffer2[10];
}

и генерирует соответствующий вывод ассемблерного кода

pushl %ebp
movl %esp,%ebp
subl $20,%esp

Автор объясняет, что, поскольку компьютеры адресуют память кратными размеру слова, компилятор зарезервировал 20 байтов в стеке (8 байтов для buffer1, 12 байтов для buffer2).

Я попытался воссоздать этот пример и получил следующее

pushl   %ebp
movl    %esp, %ebp
subl    $16, %esp

Другой результат! Я пробовал различные комбинации размеров для buffer1 и buffer2, и кажется, что современный gcc больше не дополняет размеры буфера до кратных размеру слова. Вместо этого он придерживается-mpreferred-stack-boundary вариант.

В качестве иллюстрации - используя арифметические правила статьи, для buffer1 [5] и buffer2 [13] я получу 8 + 16 = 24 байта, зарезервированных в стеке. Но на самом деле я получил 32 байта.

Бумага довольно старая, и с тех пор произошло много всего. Я хотел бы знать, что именно мотивировало это изменение поведения? Это движение в сторону 64-битных машин? Или что-то другое?

редактировать

Код скомпилирован на компьютере x86_64 с использованием gcc версии 4.8.2 (Ubuntu 4.8.2-19ubuntu1) следующим образом:

$ gcc -S -o example1.s example1.c -fno-stack-protector -m32

Ответы на вопрос(0)

Ваш ответ на вопрос