Alinhamento da memória hoje e há 20 anos

No famoso artigo "Smashing the Stack for Fun and Profit", seu autor assume uma função C

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

e gera a saída do código de montagem correspondente

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

O autor explica que, como os computadores endereçam a memória em múltiplos de tamanho de palavra, o compilador reservou 20 bytes na pilha (8 bytes para o buffer1, 12 bytes para o buffer2).

Tentei recriar este exemplo e obtive o seguinte

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

Um resultado diferente! Tentei várias combinações de tamanhos para buffer1 e buffer2, e parece que o gcc moderno não suporta tamanhos de buffer para múltiplos de tamanho de palavra. Em vez disso, cumpre o-mpreferred-stack-boundary opção.

Como ilustração - usando as regras aritméticas do papel, para buffer1 [5] e buffer2 [13], eu receberia 8 + 16 = 24 bytes reservados na pilha. Mas, na realidade, tenho 32 bytes.

O jornal é bastante antigo e muita coisa aconteceu desde então. Eu gostaria de saber o que exatamente motivou essa mudança de comportamento? É a mudança para máquinas de 64 bits? Ou alguma outra coisa?

Editar

O código é compilado em uma máquina x86_64 usando a versão gcc 4.8.2 (Ubuntu 4.8.2-19ubuntu1) assim:

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

questionAnswers(3)

yourAnswerToTheQuestion