Hardware Stack falsch simuliert?
Dienstag, 22. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  Entwicklungswerkzeuge  |  MPLAB  |  Hardware Stack falsch simuliert? « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: Hardware Stack falsch simuliert?  (Gelesen 1351 mal)
 
basti523
Newbie
*
Offline Offline

Beiträge: 21


Profil anzeigen
« am: März 22, 2010, 17:28:14 »

Hallo,

ich wollte gerade mal testen wie sich in MPLAB beim simulieren mit dem Debugger der Hardware stack verhällt wenn ich ihm mehr als 8 verschachtelte calls zu fressen gebe. Es geht um den pic16f84, also 8 Stacklevel.

Aus der Theorie konnte ich folgendes herauslesen:

Zitat
Vor dem Sprung zum ersten Befehl des Unterprogramms wird die Rücksprungadresse (= die Adresse des auf den call folgenden Befehl) auf den Stapel(= Stack) gerettet. Durch den Befehl return wird das Unterprogramm beendet. Dabei wird die Rücksprungadresse vom Stapel gelöscht und zurück in den PC(= Programm counter = Befehlszähler) geladen. Damit wird das Hauptprogramm mit dem auf den call folgenden Befehl fortgesetzt.

Das ist aus nem deutschen Buch zum PIC. Und da steht beim Rücksprung würde die Rücksprungadresse in den PC geladen und vom Stack gelöscht.

Dieses löschen vom Stack findet in der Simulation aber nicht statt. Dazu kurz zwei Bilder.



Dazu kurz noch meine Erklärung:
Alle calls inklusive "call up8" werden normal ausgeführt. Der "call up9" überschreibt den ersten stacklevel mit adresse "12". Das führt zu einer endlosschleife.
Aber es werden bei Ausführung der return befehle die alten rücksprungsdressen nicht gelöscht!

Was ist da jetzt richtig oder verkehrt? werden die rücksprungadressen vom stackspeicher gelöscht wie es in der Literatur zu lesen ist oder macht MPLAB da einen Fehler?

Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #1 am: März 22, 2010, 18:52:10 »

Zitat
werden die rücksprungadressen vom stackspeicher gelöscht... ?

Nein, denn das Löschen der Rücksprungadressen ist unnötig.

Wenn man davon ausgeht, daß TOS („Top of Stack“) ein Zeiger auf das nächste freie Element im Stack ist, passiert folgendes:

Ein „Call“ schreibt die zu sichernde Rücksprungadresse an die Stackadresse, auf welche TOS zeigt. Danach wird TOS um eins inkrementiert (und zeigt damit wiederum auf die nächste freie Speicheradresse auf dem Stack). Bei einem „Return“ wird zuerst TOS um eins dekrementiert und dann der Wert zurückgelesen. Ein Löschen findet dabei nicht statt und ist auch unnötig, da bei einem nächsten „Call“ der Wert ohnehin mit dem gewünschten und benötigten Wert überschrieben wird.   

Sinngemäß gilt das auch, wenn TOS auf die zuletzt benutzte Stackadresse zeigt. Bei einem „Call“ erfolgt dann ein Prä-Inkrement und bei einem „Return“ ein Post-Dekrement.


Viele Grüße

Bernd
Gespeichert

basti523
Newbie
*
Offline Offline

Beiträge: 21


Profil anzeigen
« Antworten #2 am: März 22, 2010, 20:54:23 »

Ja das ist genau das was ich in MPLAB simuliert bekomme. Aber warum steht dann in einem Buch über PIC´s das beim Rücksprung die Adresse in den Programmcounter geladen wird und danach vom Stack gelöscht wird?

Immerhin würde ein löschen ein anderes Verhalten bei einem Stacküberlauf hervorrufen.

Also weil bei einem Sprung in ein neuntes verschachteltes Unterprogramm mir die Rücksprungadresse im Level 1 des Stacks überschreibt. Er fängt also wenn man es als Kellerspeicher sieht wieder bei der untersten gesicherten Rücksprungadresse an und überschreibt diese. Würde ich danach mit meinen verschachtelten Unterprogrammen aufhören und den Return befehl ausführen lassen würde die Rücksprungadresse ins Hauptprogramm fehlen. Würden alle Rücksprungadressen allerdings gelöscht werden wenn der Return ausgeführt wird würde der Stackpointer beim letzten Return (wäre dann der vom up1 welcher durch den vom up8 überschrieben wurde) dann an die Rücksprungadresse von up8 springen und dort nur die gelöschte rücksprungadresse "0000" finden.

Oh man kompliziert umschrieben Smiley
Oder hab ich da jetzt einen Denkfehler?
Gespeichert
slowslow
Gast
« Antworten #3 am: März 22, 2010, 23:26:23 »

Der Stack ist eine dynamische Angelegenheit. Löschen nicht wörtlich nehmen, sondern das heißt nur, daß der Wert von Stack geholt wird (kopiert wird) und der Stackpointer dann auf einen anderen Wert zeigt.

- Manipulationen des Stacks gehen meist in die Hose.
- Stacküberlauf halte ich für einen groben Programmierfehler.

Du wünscht Dir einen definierten Sprung nach 0x0000 ? Dann vergiss einfach die herrlichen calls und arbeite mit jumps.
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #4 am: März 23, 2010, 00:22:18 »

Zitat
Aber warum steht dann in einem Buch über PIC´s das beim Rücksprung die Adresse in den Programmcounter geladen wird und danach vom Stack gelöscht wird?

Keine Ahnung, aber letztendlich ist die Darstellung, daß irgendetwas vom Stack „gelöscht“ wird, schlichtweg falsch. Wie bereits dargelegt, ist es im Prinzip vollkommen unerheblich, ob der Inhalt des Stacks gelöscht wird oder nicht. Mir ist zudem kein Hard- oder Softwarestack bekannt, der explizit freigegebene Adressen „löscht“.  Der dafür notwendige Overhead (sei es in Hard- oder Software) ist  nicht zu rechtfertigen, da es bei bestimmungsgemäßen Gebrauch nicht zu einer derartigen Situation kommen kann. Sobald ein Stack überläuft, ist das Verhalten eh mehr oder weniger zufällig. Wichtiger als das „Löschen“ ist daher eine Möglichkeit zu erkennen, ob der Stackpointer im vorgesehenen Bereich bleibt oder nicht.

Ein Sprung nach 0x0000 (bzw. dem Resetvektor des jeweiligen Controllers) beim Stacküberlauf ist meines Erachtens keine wirkliche Lösung, da er grobe Fehler im Programm möglicherweise verdecken kann. Bei einem Stack, der lediglich Rücksprungadressen speichert, mag ein Wert, der dem Reset-Vektor entspricht vielleicht noch sinnvoll sein, aber was ist ein wirklich sinnvoller Wert für einen Stack, der zudem Werte von lokalen Variablen und Funktionsparametern beinhaltet (wie bei den meisten C-Compilern)?

Die 12- und 14-Bit PICs (Anzahl der Bits bezogen auf die „instruction size“, d.h. PIC12 und PIC16) bieten keine Möglichkeit, einen Overflow  oder Underflow des Hardwarestacks zu erkennen. Die PIC18 erkennen zumindest einen Overflow des Hardwarestacks (STKFUL-Bit gesetzt oder automatischer Reset, je nach Einstellung der Configuration Bits).

Bei den dsPIC30F, dsPIC33F, PIC24H und PIC24F führt sowohl ein Overflow des Stacks als auch ein Underflow des Stacks zu einer „Trap“, d.h. einem „non maskable interrupt“ (NMI). In der Standardeinstellung der meisten Compiler (ohne explizite ISR für diese „Trap“) führt das auch zu einem Reset, aber durch eine entsprechende ISR ist ein deratig genereller Fehler im Programm relativ leicht zu erkennen und zu beheben.


Viele Grüße

Bernd
Gespeichert

basti523
Newbie
*
Offline Offline

Beiträge: 21


Profil anzeigen
« Antworten #5 am: März 23, 2010, 07:55:21 »

perfekt! vielen vielen dank jetzt bin ich endlich voll im bilde.

gruß basti
Gespeichert
Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.043 Sekunden mit 19 Zugriffen.
 
Top! Top!