Minimal ausführbare Linux-Beispiele mit Disassemblierungsanalyse
Da dies ein Implementierungsdetail ist, das nicht durch Standards spezifiziert ist, schauen wir uns nur an, was der Compiler bei einer bestimmten Implementierung tut.
In dieser Antwort werde ich entweder auf bestimmte Antworten verweisen, die die Analyse durchführen, oder die Analyse direkt hier bereitstellen und alle Ergebnisse hier zusammenfassen.
Alle diese Versionen befinden sich in verschiedenen Ubuntu / GCC-Versionen, und die Ergebnisse sind wahrscheinlich über die Versionen hinweg ziemlich stabil. Wenn wir jedoch Variationen finden, geben wir genauere Versionen an.
Lokale Variable innerhalb einer Funktion
Sei es main
oder eine andere Funktion:
void f(void) {
int my_local_var;
}
Wie gezeigt unter: Was bedeutet <Wert optimiert aus> in GDB?
-O0
: Stapel
-O3
: registriert, wenn sie nicht verschüttet werden, sonst stapeln
Die Motivation, warum der Stapel vorhanden ist, finden Sie unter: Welche Funktion haben die Push / Pop-Anweisungen, die für Register in der x86-Assembly verwendet werden?
Globale Variablen und static
Funktionsvariablen
/* BSS */
int my_global_implicit;
int my_global_implicit_explicit_0 = 0;
/* DATA */
int my_global_implicit_explicit_1 = 1;
void f(void) {
/* BSS */
static int my_static_local_var_implicit;
static int my_static_local_var_explicit_0 = 0;
/* DATA */
static int my_static_local_var_explicit_1 = 1;
}
char *
und char c[]
Wie unter: Wo werden statische Variablen in C und C ++ gespeichert?
void f(void) {
/* RODATA / TEXT */
char *a = "abc";
/* Stack. */
char b[] = "abc";
char c[] = {'a', 'b', 'c', '\0'};
}
TODO werden auch sehr große String-Literale auf den Stapel gelegt? Oder .data
? Oder schlägt die Kompilierung fehl?
Funktionsargumente
void f(int i, int j);
Muss die entsprechende Aufrufkonvention durchlaufen, z. B.: Https://en.wikipedia.org/wiki/X86_calling_conventions for X86, in der entweder bestimmte Register oder Stapelpositionen für jede Variable angegeben sind.
Dann, wie unter Was bedeutet <Wert optimiert aus> in gdb? , -O0
Dann schlürft alles in den Stapel, während -O3
versucht Register , so viel wie möglich zu nutzen.
Wenn die Funktion jedoch inline wird, werden sie wie normale Einheimische behandelt.
const
Ich glaube, dass es keinen Unterschied macht, weil Sie es wegschreiben können.
Wenn der Compiler hingegen feststellen kann, dass einige Daten niemals beschrieben werden, kann er sie theoretisch einfügen .rodata
auch dann platzieren, wenn nicht const.
TODO-Analyse.
Zeiger
Sie sind Variablen (die Adressen enthalten, die Zahlen sind), genau wie alle anderen :-)
malloc
Die Frage macht wenig Sinn für malloc
, da malloc
es sich um eine Funktion handelt, und in:
int *i = malloc(sizeof(int));
*i
ist eine Variable, die eine Adresse enthält, daher fällt sie auf den obigen Fall.
Wie Malloc intern funktioniert, wenn Sie es aufrufen, markiert der Linux-Kernel bestimmte Adressen als beschreibbar in seinen internen Datenstrukturen, und wenn sie anfänglich vom Programm berührt werden, tritt ein Fehler auf und der Kernel aktiviert die Seitentabellen, die den Zugriff ermöglichen passieren ohne segfaul: Wie funktioniert x86-Paging?
Beachten Sie jedoch, dass dies im Grunde genau das ist, was der exec
Systemaufruf unter der Haube tut, wenn Sie versuchen, eine ausführbare Datei auszuführen: Er markiert Seiten, auf die geladen werden soll, und schreibt das Programm dort. Siehe auch: Wie bringt der Kernel eine ausführbare Binärdatei zum Laufen? Linux? Abgesehen davon exec
gibt es einige zusätzliche Einschränkungen hinsichtlich des Ladeorts (z. B. ist der Code nicht verschiebbar ).
Der genaue verwendete Systemaufruf malloc
ist mmap
in modernen 2020-Implementierungen enthalten und wurde in der Vergangenheit brk
verwendet: Verwendet malloc () brk () oder mmap ()?
Dynamische Bibliotheken
Grundsätzlich mmap
in den Speicher gelangen lassen: /unix/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710
Umweltvariablen und main
'sargv
Über dem ersten Stapel: /unix/75939/where-is-the-environment-string-actual-stored TODO Warum nicht in .data?