Was ist ,,(Stack/Base)Pointer+Offset'' in der Informatik und was geben diese Wörter bei Compilern jeweils an?

2 Antworten

Offset ist die Distanz.

Der Stack wächst im Laufe der Benutzung, insbesondere wird bei dem Einsprung in eine Funktion einiges auf dem Stack abgelegt. Zusammen mit dem Aufruf gibt es den Stackframe, der reicht von Basepointer bis Stackpointer. Beide sind letztlich Markierungen und zeigen an, welcher Teil des Stacks aktuell in Verwendung ist. Der Stackpointer markiert dabei das 'obere' Ende, wo ich was 'drauflegen' kann. Jetzt ist es so, daß dieser sich im Verlauf auch einer Funktion ändern kann. Sind diese Änderunge nicht vorberechenbar, dann habe ich ein Problem, wenn ich einen Wert vom Stack durch Stackpointer+Distanz referenzieren möchte.

Und da kommt der Basepointer ins Spiel, da dieser während der Ausführung einer Funktion konstant bleibt, bieter er sich gut als Referenzmarke an, eben auch genau dann, wenn ich nicht vorberechnen kann, wie der Stackpointer seinen Wert verändert.

-----

Ich habe zuvor oben fürs Verständnis geschrieben, auf vielen Platformen ist der Stack als growdown-Stack realisiert, d.h. er wird in umgekehrter Richtung verwendet, der Stapel wächst nach unten und am unteren Ende ist der nächste freie Platz, ich lege also eigentlich drunter.

https://de.wikipedia.org/wiki/Aufrufstapel

Hier werden die Begriffe Rahmenzeiger und Stackzeiger verwendet.

----

Die CPU (Hardware) kann sich das auch zu Nutze machen, da alle lokalen Variablen unter dem Basepoiter liegen, dürfen Referenzierungen nur negative Offsets haben, andernfalls wird der Stackframe verlassen und die CPU könnte die Ausführung einfrieren. Ebenso kann die Invariante verwendet werden, daß der Stackpointer <= dem Basepointer ist.

Stackpointer bzw. Basepointer sind Zeiger, die auf ein bestimmtes Stackframe bei der Programmausführung zeigen. Solange du in der main-funktion deines Programms bist, zeigt dieser Pointer eben auf das Stackframe der main-funktion. Wenn du jetzt aus der main eine andere Funktion aufrufst, dann wird ein neues Stackframe angelegt und der Stackpointer zeigt auf das neue Stackframe. Vorher werden aber noch Rücksprungadresse und andere wichtige Daten auf den Stack gelegt, damit das Programm auch wieder zurückfinden kann.

Ein Offset ist die Distanz von einem Datenwort oder einem Byte (abhängig davon, ob Speicher Wort- oder Byteadressiert ist) zum jeweiligen Base-Pointer.


nelli155 
Beitragsersteller
 13.05.2022, 20:40

Und warum braucht man jetzt beides zusammen? Es ist ja bei einem Compiler folgendermaßen:

Der Compiler sagt also z.B. in einer Funktion brauche ich folgende Variablen (Liste der symbolischen Namen und Speichergrößen). Dann plant er dafür Platz auf dem Stack ein und weist jedem symbolischen Namen die Adresse in Form von (Stack/Base)Pointer+Offset zu. Jetzt kann er die einzelnen Statements, die die Variablen nutzen möchten auf ASM abbilden und eben die festgelegten Adressen dabei eintragen (IP+Offset, bzw. BP-Offset).

Und hier stellt sich die Frage, warum man den Pointer UND einen Offset braucht. Warum reicht nicht ein Pointer aus, weil der zeigt ja direkt auf eine gewünschte Stelle?

0
mobly666  13.05.2022, 21:56
@nelli155

Der Stackpointer existiert ja sowieso schon für das aktuelle Stackframe. Du kannst es dir jetzt einfach machen und für jede einzelne Variable einen eigenen Pointer speichern, oder aber du überlegst etwas und kommst zu dem Schluss, dass diese Variablen alle eine Gemeinsamkeit haben: sie sind alle im aktuellen Stackframe vorhanden und teilen sich damit die Basisadresse des Stackframes. Wozu sollte man also jedes Mal eine vollständige Adresse für jede Variable speichern, wenn die ohnehin alle im gleichen Stackframe liegen? Das wäre viel Redundanz und würde auch mehr Speicher brauchen. Du merkst dir dann pro Variable nur den Offset, also die Differenz zum Basepointer und erreichst dein Ziel immer durch Addition von Basepointer und Offset.

Oder versinnbildlicht: All deine Freunde wohnen in der selben Straße - in der Lindenstraße.

Max wohnt in der Lindenstraße 8, Moritz in der Lindenstraße 24 und Luisa wohnt in der Lindenstraße 64. Statt dir jetzt für jeden dieser Freunde die vollständige Adresse zu merken:

Max: Lindenstraße 8

Moritz: Lindenstraße 24

Luisa: Lindenstraße 64

merkst du dir nur:

Basepointer: Lindenstraße

Max: 8

Moritz: 24

Luisa: 64

und hast so weniger Redundanzen. Zu deinem Ziel kommst du aber durch Addition trotzdem noch.

2