Ein Trick, der nicht portabel ist oder gar nicht garantiert funktioniert, besteht darin, einfach die Adresse eines Einheimischen als Hinweis auszudrucken.
void print_stack_pointer() {
void* p = NULL;
printf("%p", (void*)&p);
}
Dadurch wird im Wesentlichen die Adresse von p
ausgegeben das ist eine gute Annäherung an den aktuellen Stapelzeiger
Dafür gibt es keine tragbare Möglichkeit.
In GNU C kann dies für Ziel-ISAs funktionieren, die ein Register namens SP haben, einschließlich x86, wo gcc "SP" als Abkürzung für ESP oder RSP erkennt.
// broken with clang, but usually works with GCC
register void *sp asm ("sp");
printf("%p", sp);
Diese Verwendung lokaler Registervariablen wird jetzt von GCC abgelehnt:
Die einzige unterstützte Verwendung für diese Funktion ist die Angabe von Registern für Eingabe- und Ausgabeoperanden beim Aufruf von Extended asm
Durch die Definition einer Registervariablen wird das Register nicht reserviert. Außer beim Aufrufen des erweiterten asm wird der Inhalt des angegebenen Registers nicht garantiert. Aus diesem Grund werden die folgenden Verwendungen ausdrücklich nicht unterstützt. Wenn sie zu funktionieren scheinen, ist das nur Zufall , und funktioniert möglicherweise aufgrund von (scheinbar) nicht zusammenhängenden Änderungen im umgebenden Code oder sogar geringfügigen Änderungen in der Optimierung einer zukünftigen Version von gcc nicht mehr wie beabsichtigt. ...
Es wird auch in der Praxis mit clang gebrochen, wo sp
wird wie jede andere nicht initialisierte Variable behandelt.
Zusätzlich zur Antwort von duedl0r mit speziell GCC Sie könnten __builtin_frame_address(0)
verwenden was GCC-spezifisch ist (aber nicht x86 spezifisch).
Dies sollte auch auf Clang funktionieren (aber es gibt einige Fehler).
Es ist auch eine Lösung, die Adresse eines Einheimischen zu nehmen (wie JaredPar antwortete).
Beachten Sie, dass AFAIK der C-Standard theoretisch keinen Call-Stack benötigt.
Man könnte von einer anderen Technik träumen. Und Sie könnten Stapel geteilt haben (zumindest auf dem neuesten GCC), in diesem Fall hat der Begriff des Stapelzeigers viel weniger Sinn (weil der Stapel dann nicht zusammenhängend ist und aus vielen Segmenten mit jeweils wenigen Aufrufrahmen bestehen könnte). .