Forum: Mikrocontroller und Digitale Elektronik Avr Stack


von Airbag (Gast)


Lesenswert?

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?

von Airbag (Gast)


Lesenswert?

Sorry meine eintrag ist volle fehler sorry. Ich habs eilig gehabt da ich
diese Praktikum irgend wie hinter mir bringen will

von crazy horse (Gast)


Lesenswert?

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.

von Dave (Gast)


Lesenswert?

ö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

von Dave (Gast)


Lesenswert?

@crazy horse  na klar.. war wieder zu spät ... g


dave

von Airbag (Gast)


Lesenswert?

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.

von Airbag (Gast)


Lesenswert?

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).

von Dave (Gast)


Lesenswert?

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

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.