Avr Stack

Gast #123998
Es wird zwar über all in den Tutorialien erwähnt wo zu der Stack da ist
aber es gibt keine  expliziete Beispiele zum beispiel wie sieht der
rück sprung adresse nach eine Bearbeitung von eine Interrupt, wie
bringe ich Assembler die Rücksprungsadresse ích hab gegooglt bis ich
müde bin gibt es irgend welche Webseiten?
2 Frage ist ich kenne mich gut mit C aber Assembler scheint einige
hürden zu haben wie siehen die if Anweisungen aus z.b If(A<0) mir fehlt
eigentlich nicht andres ein als eine als so etwas
 z.b sagen wir so die ergebnisse von A sein in r16
 dann würde ich die null in eine Register laden dann von 0 subtrahieren
wenn dann gucken ob diese wert gucken ob er negativ ist dann mit einen
Sprung. Gibt es auch andere tricks?
Gast
Um den Stack brauchst du dich normalerweise kaum kümmern - am Anfang des
Programms den SP laden, der Rest geht von alleine, die nötige Disziplin
vorausgesetzt.
Einmal wird der Stack für die Rückkehradresse benutzt, geschieht
automatisch bei call/return, ebenso bei Interrupt/reti.
Desweiteren gibts die Möglichkeit zum Sichern/Zwischenspeichern von
Registern, ein push legt einen Wert auf den stack, ein pop holt sich
den Wert wieder, der SP selbst wird dabei automatisch aktualisiert.
Bleibt noch die Möglichkeit, den SP direkt zu beinflussen. Das kann
Programmiervorteile bringen, eiserne Disziplin ist aber nötig, sonst
geht das schief. Besser für solche Sachen die Indexregister x, y und z
benutzen, die erlauben auch noch mehr Adressierungsarten (mit/ohne
offset, automat. inc/decrementieren).

Zum Vergleich: wird mit compare (cpi: Vergleich mit einer Konstanten),
die Flags werde wie bei einer Subtraktion gestzt, die Subtraktion
selbst wird aber nicht durchgeführt. Anschliessend kannst du mit
diversen bedingten Sprüngen verzweigen.
Gast
öhm also deutsch hast du schon gelernt? g

also sagen wir du hast nen interrupt:

programmadresse (16bit) also 2x8bit wird auf den stack geladen..
...interrupt ausführung
...
reti: die adresse wird runter geholt, in den program counter übergeben,
dann springt er da hin

mit push kannste einfach so nen byte drauflegen und mit pop runter
holen.. aber auf ein push immer schön ein pop! sonst haste stäck
overflow.. und er rennt deine register übern haufen..(das nebenbei)

if befehle..
willste: if r16 = 20 dann machste
cpi r16, 20
brne war_nicht
; mach irgendwas, wenns 20 war
war_nicht:
;hier gehts auf jedenfall weiter..

der befehl brne hies: branch (verzweige) if NOT equal, wenn der
vergleich NICHT 0 war.. also 20-20 = 0, das wäre equal, dann würde er
NICHT springen, und das machen was zwischen dem branch und war_nicht
steht.

im datenblatt findeste noch viele schöner andere branch.. vergleich bar
mit =, <, > etc.
breq   equal
brne   not equal
brmi   if minus

dave
Gast
Also  du meinest wenn ich den stack am anfang intialisiert hab dann
brauch ich mich nach aufruf eine Funktion nicht drum kümmern? kehrt er
dann direkt nach dem z.b recall subx macht er da dann weiter.
Gast
also zu meine deutsch ich bin Schwede. Aber danke für deine gründliche
Antwort. Die befehle kenn ich schon das problem ist nur ob ich ohne
subsitution folgende Anweisungen realisieren kann if(x<0) oder if(x>0).
Gast
achso.. ja dann nehm ich das mit der sprache zurück hehe..

also ich wüsste keine -einfache- möglichkeit ein x<0 zu erkennen.. an
einem byte steht seltenst - dran.. da müsstest du ein weiteres bit 8
einführen oder bit 7 dafür missbrauchen.. entsprechendes gilt für
x>0..
solche instruktionen kannste eigentlich nur einfach anwenden, wenn du
gerade einen rechenschritt gemacht hast..
sub r16, r17
brmi  (branch if minus)
brpl  (branch if plus)

zu beachten gibt's: 0 kann ganz schön viele branch zum anspriengen
bringen.. brmi+brpl wäre ein beispiel

zum stäck:
eigentlich musste garnichts machen... nur wird (wie crazy horse schon
sagte) der stack gerne mal zum systematischen zwischenlagern
gebraucht.. wenn du in nen irq springst, solltest du natürlich die
register speichern, die du im irq veränderst (sonst bekommste probleme)
und da kann man quick and "dirty" (nicht dirty) den stack nehmen...

irq_routin:
 push temp1
 in temp1, sreg
 push temp1
 ...
 ...
 ...
 pop temp1
 out sreg, temp1
 pop temp1
 reti


dave

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 22 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.