Ich bin auf einen Code gestoßen void *p = &&abc;
. Welche Bedeutung hat &&
hier? Ich kenne rWert-Referenzen, aber ich denke &&
, dass die Verwendung in diesem Zusammenhang anders ist. Was bedeutet &&
in void *p = &&abc;
?
Ich bin auf einen Code gestoßen void *p = &&abc;
. Welche Bedeutung hat &&
hier? Ich kenne rWert-Referenzen, aber ich denke &&
, dass die Verwendung in diesem Zusammenhang anders ist. Was bedeutet &&
in void *p = &&abc;
?
Antworten:
&&
ist die Erweiterung von gcc , um die Adresse des in der aktuellen Funktion definierten Labels abzurufen.
void *p = &&abc
ist in Standard C99 und C ++ illegal.
Dies wird mit g ++ kompiliert.
void*
.
__forceinline
? __declspec(naked)
? Einer meiner Lieblings-MSVCisms ist : template<typename T> class X { friend T; }
, der ungültige C ++ 03 ist.
Das ist die Adresse eines Etiketts und eine für GCC spezifische Funktion .
int main(void) {
void* startp;
s:
startp = &&s;
printf("the assignment above starts at address %p\n", startp);
return 0;
}
Sie hätten es selbst herausfinden können, indem Sie Folgendes getestet haben:
int main(void) {
void* startp;
int a;
startp = &&a;
printf("startp=%p\n", startp);
return 0;
}
In diesem Fall sagt GCC:
Fehler: Bezeichnung 'a' verwendet, aber nicht definiert
Sie müssen Assembler kennen, um dies wirklich zu verstehen, aber ich werde versuchen, Ihnen zu erklären, was eine Adresse eines Etiketts bedeutet.
Nachdem das Betriebssystem die EXE-Datei von der Festplatte geladen hat, eine Komponente des Betriebssystems namens "The Loader" (Windows hat den "PE Loader", Linux hat "ELF Loader" oder vielleicht sogar andere, wenn sie in der kompiliert sind Kernel), es macht eine "Virtualisierung" dieses Programms und verwandelt es in einen Prozess.
Dieser Prozess glaubt, dass es der einzige im RAM ist und Zugriff auf den gesamten RAM hat (dh 0x00000000-0xFFFFFFFF auf einem 32-Bit-Computer).
(Das Obige ist nur ein kurzer Überblick über das, was passiert. Sie müssen wirklich die Montage lernen, um es vollständig zu verstehen.
Das Label in einem Quellcode ist im Grunde eine Adresse. "gehe zu Etikett;" macht nichts anderes als einen Sprung zu dieser Adresse (denken Sie an den Befehlszeiger in der Assembly). Dieses Etikett speichert diese RAM-Adresse, und so können Sie diese Adresse herausfinden.
Nachdem Sie ASM gelernt haben, werden Sie feststellen, dass diese Adresse auf eine Anweisung im .text
Abschnitt der ausführbaren Datei verweist . Der .text
Abschnitt enthält den (Binär-) Code Ihres Programms, der ausgeführt werden soll.
Sie können dies überprüfen mit:
objdump -x a.out
Wie in GCC beschrieben , können Sie damit eine Sprungtabelle initialisieren. Einige Scannergeneratoren wie re2c (siehe -g
Parameter) verwenden dies, um kompaktere Scanner zu generieren. Vielleicht gibt es sogar einen Parser-Generator, der dieselbe Technik verwendet.