Forum: Mikrocontroller und Digitale Elektronik Probs mit Stackbeiträgen im tutorial


von Matthias Beckmann (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
ich hab mir die Zusatzinfos von Lothar Müller (Der Stack Teil 1-3)
http://www.mikrocontroller.net/attachment.php/675/Der-Stack-2.pdf
einmal durchgelesen und wollte mir das ganze mal im Simulator von
Studio4 genauer anschaun. So weit, so gut und auch vielen Dank, daß es
Leute gibt, die sich die Mühe machen, so viel aufzuschreiben.
Aber: ;-)
ich versteh bei Teil2 nicht, wie das Unterprogramm funktionieren soll,
oder liegen meine Fehler daran, daß ich es mit einem ATtiny26 versucht
hab, und die bemängelten befehle auf dem garnicht funktionieren?
ich hab das programm aus Teil 2 einmal mit einem init
zusammengeschustert, ist im anhang.
ich hab SPL in SP, ZLow in Z, ZHigh ganz weg und call in rcall
umgewandelt.
aber die Zeilen
mov Z, SP
add Z, 4
machen mir (und dem Studio4simulator) probleme. ich kann SP nicht in Z
"moven" habs also mit
in Z, SP
probiert, aber dann wurde Z bemängelt oder nicht erkannt, wenn ichs mit
temp ersetze gehts, aber dann müsste ich das ja auch nich pushen usw.
dann versteh ich ja gar nichts mehr. :-) ich wollte ja erstmal
verstehen, was da gemacht wird.
ja und: add geht doch nur mit registern, und nicht mit werten, also
müsste ich 4 erst in ein temp1 und daß dann in z, welches ja wieder
nicht erkannt wird. hmm, mit ST z, temp könnts gehen, aber da weiß ich
nicht, ob daß dann wieder etwas anderes auslöst.
Kann mir jemand bei dem helfen, was ich eigentlich wissen wollte,
nämlich so etwas wie eine Maske für ein Unterprogramm, wie im Beitrag
von Lothar Müller, die mir die möglichkeit gibt register zu benutzen,
ohne informationen zu verlieren?
Vielen Dank im Voraus,
Matthias

von Frank Linde (Gast)


Lesenswert?

Ich kenne das Tutorial nicht, aber die Befehle "MOV ZLow, SPL" und
"ADD ZLow, 4" werden auch auf keinem anderen AVR-Controller
funktionieren, weil sie schlichtweg falsch sind. Auf dem Tiny26 kommt
dann noch dazu, dass ZLow und SPL nicht definiert sind.

Der MOV-Befehl kann nur zwischen Registern kopieren, der Stackpointer
ist aber eine I/O-Adresse und kein Register. Und der ADD-Befehl kann
ebenfalls nur Register addieren - und "4" ist eher kein Register.

Gruß, Frank

von Conlost (Gast)


Lesenswert?

Hallo Mattias,

mach es so wie ich, lade dir mal die ganzen Befehle runter,
dann kannst du genau nachlesen wie und wann man welchen
Befehl benutzen kann bzw sollte.

http://www.atmel.com/dyn/resources/prod_documents/DOC0856.PDF

Ich hoffe es hilft dir etwas.

Gruß,
Arno

von Matthias Beckmann (Gast)


Angehängte Dateien:

Lesenswert?

ja, da sind gute erklärungen dazu, mehr als beim Datenblatt eines jeden
MCs im Instruction Summary.
Aber wie ich den Z-pointer benutze weiß ich immernoch nicht...
ich hab mal weitergeschriebne, die kommentage sind daneben (im anhang),
aber das was das programm machen sollte, nämlich $10 und $20 addieren
klappt nicht wirklich.

von Conlost (Gast)


Lesenswert?

Hallo Mtthias,

ich hab mir das mal angeschaut und blicke da auch nicht durch.
Addieren kann man doch auch ohne diesen ganzen trickreichen
Krempel. Das ist nur was für Spezialisten.  :-)

Gruß,
Arno

von Matthias Beckmann (Gast)


Lesenswert?

naja, das addieren is natürlich nur ein beispiel für ein beliebiges
Unterprogramm, bei dem man nicht daraur achten muß, welche register man
verwendet, da sie alle gesichert werden (sollten).
Da das ja aber im tutorial dieser Seite steht, dacht ich es sei nicht
nur für spezialisten, nur die sache wie zB add Z, 4 sind ja richtig
falsch, ich komm nur nicht drauf, wies gemeint war, oder sein sollte.
Matthias

von Conlost (Gast)


Lesenswert?

Der Stack wird üblicher Weise dazu benutzt die Rückkehradresse
zu speichern, wenn man in eine Interruptroutine oder in ein
Unterprogramm springt. Denn sonst weiss der Prozessor nicht
wohin er soll wenn er den "reti" oder "ret" Befehl im
Programm vorfindet.

Gruß,
Arno

von Frank Linde (Gast)


Lesenswert?

Hallo Matthias,

was Du genau erreichen möchtest, habe ich auch noch nicht verstanden,
aber mit ST und LD bist Du vermutlich auf der falschen Spur. Das
Z-Register ist ein 16-Bit-Register, bestehend aus den beiden
8-Bit-Registern ZL = R30 (Low-Byte) und ZH = R31 (High-Byte). Wenn Du
es  direkt beschreiben möchtest, kannst Du das byteweise mit LDI oder
MOV erreichen.

Gruß, Frank

von Conlost (Gast)


Lesenswert?

Hollo Frank,

Matthias hat versucht im Tutorial im Abschnitt Stack die dort
beschriebenen Beispiele auszuprobieren.
Nur leider geht das nicht wie ich auch festgestellt habe.
Schau dir bitte mal den Abschnitt an um den es geht.

http://www.mikrocontroller.net/attachment.php/675/Der-Stack-2.pdf

Hier wird der Stack als Datenübergaberegister "missbraucht",
nur funktioniert das irgendwie nicht.
Ich bin selber erst Anfänger und blicke da auch nicht durch.
Eventuell kannst du uns ja etwas helfen.

Gruß,
Arno

von Frank Linde (Gast)


Lesenswert?

Schaue ich mir gerne einmal an, aber das wird erst später am Tag etwas
geben, weil zunächst andere Arbeiten anstehen. Wenn das, was Matthias
als "Original" in seinem Quelltext stehen hat, tatsächlich eine 1:1
Kopie des Tutorials ist, dann ist das Tutorial an dieser Stelle aber
fehlerhaft, wie ich oben schon geschrieben habe.

Bis später,

Frank

von Conlost (Gast)


Lesenswert?

Danke Frank, es eilt ja nicht.

Gruß,
Arno

von Matthias Beckmann (Gast)


Angehängte Dateien:

Lesenswert?

So, ich hab nochmal was verändert, und jetzt macht das programm
wenigstens was es soll, 2 werte addieren.
die kommentare stehen daneben.
der z-pionter ist also der "zeiger" (was auch sonst)darauf, was Z
enthält, was ich mit befehlen wie ld und st dann in register schieben
kann und was ich aus dem stack ziehe, ohne daß er "zusammenbricht",
weil ich den wert nicht wirklich rausziehe, sondern nur kopiere oder
so, oder??
hmm, so ganz blick ich immer noch nicht durch.
Matthias

von Frank Linde (Gast)


Angehängte Dateien:

Lesenswert?

So, ich habe gerade mal einen Blick auf den Text geworfen. Die Theorie
ist korrekt, aber bei der Umsetzung in die Praxis haben sich einige
Fehler eingeschlichen. Ich versuche mal, es besser zu machen, wobei ich
mich immer auf den ATMEL-Assembler im AVR-Studio beziehe:

Der Befehl CALL steht nicht bei allen AVR-Typen zur Verfügung, ggf. muß
auf RCALL geändert werden.

Das Hauptprogramm muß in einer Endlosschleife "gefangen" werden,
sonst wird das UP erneut durchlaufen und das Ergebnis ist Chaos.

Das Z-Register ist ein 16-Bit-Register und ist zusammengesetzt aus den
beiden 8-Bit-Registern R30 und R31. Diese beiden Teilregister werden
nicht mit ZLow und ZHigh angesprochen, sondern mit ZL und ZH.

Der Stack wird nur bei den AVR-Typen mit mehr als 256 Byte RAM über SPL
und SPH angesprochen, welche dann zusammen einen 16-Bit-Zeiger ergeben.
Die Typen mit weniger RAM benötigen dazu nur einen 8-Bit-Zeiger und der
wird als SP angesprochen.

Der Stack ist kein Universalregister und kann deshalb nicht mit MOV
angesprochen werden. Dazu sind die Befehle IN oder OUT geeignet.

Beim Befehl ADD können als Argumente nur Register verwendet werden,
keine Zahlen. Man muß für die Addition also ein Zwischenregister
bemühen. Einige AVR (u.a. auch der von Matthias verwendete tiny26)
kennen für die Manipulation der 16-Bit-Register mit einem direkten
Zahlenwert auch den Befehl ADIW, der deshalb hier verwendet wird.

Das entsprechend geänderte Programm von Matthias findet Ihr im Anhang.
Hoffentlich habe ich jetzt nichts übersehen...

Noch ein Hinweis: Der Autor arbeitet in seiner Überschlagsrechnung mit
maximal 100 Byte Speicherbedarf für den Stack. Das mag für viele
Programme auch ausreichend sein, aber eben nicht für alle, denn sonst
gäbe es den 16-Bit-Stackzeiger wohl nicht. Falls man einen 16-Bit-Stack
hat, sollte man deshalb IMHO im Falle eines Eingriffs in diesen Zeiger
auch immer mit 16 Bit rechnen, sonst kann es Ärger geben. Hier habe ich
das aber nicht gemacht, da im Beispiel von 128 RAM ausgegangen
wurde.

Gruß, Frank

von Conlost (Gast)


Lesenswert?

Hallo Frank,

besten Dank für deine Mühe.

Gruß,
Arno

von Frank Linde (Gast)


Lesenswert?

Hallo Matthias,

da haben sich unsere Postings überschnitten. "Oder so" ist richtig.
;-)

Der Z-Zeiger zeigt nicht auf das, was das Z-Register enthält! Wenn Du
einen Moment darüber nachdenkst, wirst Du sehen, dass dies ein
zirkulärer Verweis wäre, der wenig sinnvoll ist. ;-)

Der Z-Pointer wird in diesem Fall als Zeiger auf eine Speicherstelle im
RAM benutzt. Diese Speicherstelle wird mit dem LD-Befehl ausgelesen,
aber nicht verändert. ST überschreibt die Speicherstelle mit einem
neuen Wert. Das Ganze wird als Indirekte Adressierung bezeichnet. Im
Datenblatt und bei den Befehlserklärungen zu LD, ST in der Hilfe
findest Du weitere Erläuterungen.

Am besten schaust Du Dir das mal im AVR-Studio im Einzelschrittmodus
an, dann siehst Du sehr schön, was genau passiert. Ist bestimmt
einleuchtender, als eine langatmige schriftliche Darstellung...

Gruß, Frank

von Matthias Beckmann (Gast)


Lesenswert?

Da hast du recht, das hatte ich ja auch ursprünglich vor, da man meist
alles besser versteht, wenn man sichs kleinschrittig anschaut. Nur
waren dort eben diese Fehler, die das verhinderten.
Aber vielen Dank für deine Erklärung, jetzt ist einiges klarer.
Grüße,
Matthias

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.