PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : register retten



eis
07.07.2007, 18:32
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

JanB
07.07.2007, 18:58
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, 18: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. :)

PicNick
07.07.2007, 19:14
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, 19:44
dafuer warst du am ausfuehrlichsten :)

eis
07.07.2007, 19:47
@janb
@fluchtpunkt
@PicNick
vielen Dank für eure schnellen und ausführlichen Antworten.
jetzt hab ichs endlich geschnallt.

gruss alex