www.mikrocontroller.net

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


Autor: Michael B. (gm8816)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jedes push braucht genau ein pop!

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Troll Blaubär (blaubeer)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Stackpointer initialisiert?

MfG Spess

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.