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