Archiv verlassen und diese Seite im Standarddesign anzeigen : register retten
Hi, ich hab' da mal ne frage
und zwar geht es um folgende Passage aus einem Beispielprogramm:
initm16: push r16 ;Register retten
ldi r16,$ff
out DDRB;r16;
pop r16 ;Register zurück
ret
was ich nicht ganz verstehe - was sollen diese Befehle push und pop eigentlich bewirken?Im Buch habe ich leider keine vernünftige Antwort gefunden,in der Wiki auch nicht.
und überhaupt - wie kann man ein Register retten? und vor allem wovor?
kann mir das jemand bitte kurz erklären?
vielen dank schonmal im voraus
Hallo,
der Assembler Befehl PUSH <Register> legt den Inhalt des Registers
auf dem Stack ab. (Stichwort: LIFO)
Der POP <Register> Befehl tut genau das Gegenteil, er lädt
den obersten Wert vom Stack in das Register.
Der Hauptzeck dieser Befehle ist das temporäre "Retten" von Registerinhalten,
weil der Inhalt später noch gebraucht wird.
In deinem Codebeispiel wird der Inhalt von R16 mit PUSH R16 auf den Stack gerettet.
Dann wird R16 mit dem Wert $FF geladen um dies nach DDRB auszugeben.
Anschliessend wird mit POP R16 der alte Wert von R16 wiederhergestellt.
Gruß Jan
fluchtpunkt
07.07.2007, 19:58
Das Register wird vor der Aenderung gerettet.
push legt den Wert des Registers ganz oben auf den Stack. (google hilft)
Dann wird irgendwas mit dem Register gemacht, es bekommt einen neuen Wert. Dieser neue Wert wuerde jedoch das Hauptprogramm "verwirren".
Am Ende des Teilprogramms holt deshalb der Prozessor per pop den vorher gespeicherten Wert des Registers zurueck und versetzt das Register somit in den "Ausgangszustand".
Man soll seinen Arbeitsplatz ja immer so verlassen wie man ihn vorgefunden hat. :)
Also:
Es gibt im Speicher ein Bereich, das heißt "Stack", und ist meistens ganz oben in der freien Memory (=Speicher)
Dazu gibt's auch einen Zeiger, (Stackpointer), der zu Beginn mit der OBERSTEN Adresse von diesem Bereich geladen wird.
So.
Wenn man nun ein Register "retten" will, d.h. man will den Inhalt sichern, weil man dieses Register eine Zeitlang für was anderes braucht (Manche Subroutinen tun sowas) sagt man laut und deutlich "PUSH register"
Die CPU subtrahiert nun 1 von dem "Stackpointer" und schreibt den Inhalt des Register dorthin, wo der "Stackpointer" nun hinzeigt.
Nun kann man ohne gewissenbisse das Register vernudeln.
Recht's einem, sagt man "POP register"
Die CPU kopiert nun den Wert von dort, wo der Stackpointer hinzeigt, wieder ins register und addiert 1 auf den Pointer.
Nun ist wieder alles so, wie es Vor dem PUSH war.
Klaro ?
Weil das also ein "FIrst-in Last-Out" Speicher ist, sind im Code PUSH und POP gewissermassen gespiegelt drin, z;b,
PUSH r1 retten (=save)
PUSH r2 retten (=save)
CALL subroutine ;(die kann nun diese beiden register für sonstwas verwenden)
POP r2 wiederherstellen (=restore)
POP r1 wiederherstellen (=restore)
; jetzt ist alles wie vorher
*lufthol*
hilft dir das ?
EDIT:
@fluchtpunkt: sorry
@janb auch sorry, ich war wohl am langsamsten
fluchtpunkt
07.07.2007, 20:44
dafuer warst du am ausfuehrlichsten :)
@janb
@fluchtpunkt
@PicNick
vielen Dank für eure schnellen und ausführlichen Antworten.
jetzt hab ichs endlich geschnallt.
gruss alex
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.