Speicherausrichtung heute und vor 20 Jahren

n der berühmten Zeitung "Smashing the Stack for Fun and Profit" übernimmt der Autor eine C-Funktio

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

und generiert die entsprechende Assembly-Code-Ausgabe

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

Der Autor erklärt, dass der Compiler 20 Bytes auf dem Stack reserviert hat (8 Bytes für Puffer1, 12 Bytes für Puffer2), da Computer den Speicher in Vielfachen der Wortgröße adressieren.

Ich habe versucht, dieses Beispiel neu zu erstellen und habe das folgende @ erhalt

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

Ein anderes Ergebnis! Ich habe verschiedene Größenkombinationen für buffer1 und buffer2 ausprobiert, und es scheint, dass der moderne gcc die Puffergrößen nicht mehr auf ein Vielfaches der Wortgröße auffüllt. Stattdessen bleibt das-mpreferred-stack-boundary Möglichkeit

Zur Veranschaulichung: Wenn ich die Rechenregeln des Papiers für buffer1 [5] und buffer2 [13] verwende, werden 8 + 16 = 24 Bytes auf dem Stapel reserviert. Aber in Wirklichkeit habe ich 32 Bytes.

Das Papier ist ziemlich alt und seitdem ist viel passiert. Ich möchte wissen, was genau diese Verhaltensänderung motiviert hat? Ist es der Schritt in Richtung 64-Bit-Maschinen? Oder etwas anderes

Bearbeite

Der Code wird auf einem x86_64-Computer mit gcc Version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) wie folgt kompiliert:

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