Forum: Mikrocontroller und Digitale Elektronik Ret Befehl funktioniert nach Push Befehl nicht mehr


von Michael B. (gm8816)


Lesenswert?

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.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

jedes push braucht genau ein pop!

von Johannes M. (johnny-m)


Lesenswert?

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!

von Johannes M. (johnny-m)


Lesenswert?

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.

von Troll B. (blaubeer)


Lesenswert?

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

von Spess53 (Gast)


Lesenswert?

Hi

Stackpointer initialisiert?

MfG Spess

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.