Hallo, nachdem ich ein Unterprogramm mit rcall aufgerufen habe und in diesem Unterprogramm Register sichern will funktioniert der Befehl ret nicht mehr. Das Programm springt immer wieder an die Adresse 0x0000 zurück. Ich benutze den ATtiny84. Der Stackpointer wurde bereits initialisiert und funktioniert auch. Ich habe es mit anderen Unterprogrammen versucht. Es passiert nur, wenn ich den Befehl push aufrufe.
Läubi Mail@laeubi.de wrote:
> jedes push braucht genau ein pop!
Ja, und v.a. in der richtigen Reihenfolge! Wenn Du was pushst, musst Du
es VOR dem nächsten ret(i) auch wieder poppen!
Kleiner Zusatzhinweis zur Arbeit mit dem Stack: Der Stack ist ein LIFO (Last In First Out)-Speicher, d.h. es kann immer nur auf das zuletzt dort abgelegte Element zugegriffen werden. Wenn auf dem Stack eine Rücksprungadresse liegt (von einem call oder einem Interrupt) und Du legst danach mit push ein Datenbyte auf den Stack, dann liegt das gepushte Datenbyte oben auf dem Stack. Wenn dann das ret(i) kommt und die Rücksprungadresse abholen will, findet es aber nicht die Rücksprungadresse, sondern das gepushte Datenbyte vor. Das führt dann i.d.R. zu einem Systemabsturz, weil das was da auf dem Stack liegt zumindest nicht die richtige Adresse für den Rücksprung ist (was zumindest ein unvorhergesehenes Verhalten zur Folge hat) oder sogar eine ungültige Adresse ist (das dürfte dann einen Reset geben). Deshalb muss alles was gepusht wird, auch in der umgekehrten Reihenfolge wieder gepopt werden.
Ergänzung: Jeder Sprung (egal ob per (r)jmp, ijmp, (r)call, icall ret(i) oder ein bedingter Sprung an eine Adresse hinter den benutzten Teil des Programmspeichers, lässt den Programmcounter bis zum nächsten gültigen Befehl hochzählen ("durchrattern"). Da der Adressbereich als Ring angesehen werden kann, folgt nach der letzten Adresse die Adresse 0. Rücksprünge bei vermorkeltem Stack landen gern mal hinter dem benutzten Adressbereich. MfG, 5406
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.