PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Push und Pop beim Assembler?


dudelicios
2005-07-02, 19:50:12
Hallo,

was machen PUSH und POP beim Assembler und bei welchen Gelegenheiten wendet man sie an? Sie treten vorzugsweise in Unterprogrammen auf (z. B. wenn man sie mit call auruft).

Zählt PUSH eine Zahl im Stackpointer (hoch bzw. runter) und zeigt dadurch auf eine Adresse im Stack, in welchem ein bestimmtes Register gesichert wird? POP kopiert dann den Wert vom Stack in das Register zurück und verringert dann den Stackpointer um 1?

Ist das so korrekt? Zu welchen Gelegenheiten braucht man das? Aus den Suchergebnissen bei Google werde ich nicht schlau, auch wenn einige brauchbare Infos enthalten.

zeckensack
2005-07-02, 20:37:20
Hallo,

was machen PUSH und POP beim Assembler und bei welchen Gelegenheiten wendet man sie an? Sie treten vorzugsweise in Unterprogrammen auf (z. B. wenn man sie mit call auruft).

Zählt PUSH eine Zahl im Stackpointer (hoch bzw. runter) und zeigt dadurch auf eine Adresse im Stack, in welchem ein bestimmtes Register gesichert wird? POP kopiert dann den Wert vom Stack in das Register zurück und verringert dann den Stackpointer um 1?PUSH reg verringert ESP um 4*, und speichert reg nach [ESP], ergo "auf den Stack".

POP reg macht das gleiche rückwärts. Erst wird reg mit dem Wert in [ESP] geladen, und dann ESP um 4* erhöht. Dh reg wird "vom Stack geholt".

*im 32 Bit-Modus
Ist das so korrekt? Zu welchen Gelegenheiten braucht man das? Aus den Suchergebnissen bei Google werde ich nicht schlau, auch wenn einige brauchbare Infos enthalten.Das macht man deswegen, weil man die Register-Inhalte nicht einfach zerstören darf. Die übergeordnete Funktion (die die aktuelle Funktion aufgerufen hat), nutzt die Register ja ebenfalls. Man muss also, bevor man die Register nutzt, erstmal deren alten Inhalt sichern, und wenn die Funktion verlassen wird, diese alten Inhalte wiederherstellen. Dafür bietet sich der Stack an.
a)Man kann sehr einfach Speicher "alloziieren", indem man einfach ESP verringert, und umgekehrt wieder freigeben indem man ESP erhöht.

b)Man spart sich komplexe Speicherallokatoren ... die man eh' nicht ausführen könnte, so lange man noch nicht alle Register gesichert hat.

c)Da malloc/free nicht geht, wäre die dritte Möglichkeit zur Sicherung von Registerinhalten globale Variablen. Auch dies erspart man sich gerne durch den Stack.
Das ist insbesondere wichtig in Situationen mit mehreren Threads. Man bräuchte, wenn es den Stack nicht gäbe, für jede Funktion und für jeden Thread extra globale Variablen, nur um die Register zu sichern. Das ist nicht nur extrem unelegant, sondern auch sehr kompliziert und fehlerträchtig. Der Stack dagegen ist pro Thread sowieso separat. Und da jede Funktionsebene am Stack einfach nach unten anbaut, braucht man sich um die Verwaltung kaum Sorgen zu machen. Stacks sind extrem simpel und leicht zu verstehen, aber trotzdem robust.

Neomi
2005-07-03, 00:35:58
c)Da malloc/free nicht geht, wäre die dritte Möglichkeit zur Sicherung von Registerinhalten globale Variablen. Auch dies erspart man sich gerne durch den Stack.

Auch ohne parallele Threads würde ein Set globaler Variablen pro Funktion nicht ausreichen. Alternativ wäre keine Rekursion mehr möglich.