PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Stacktiefe PIC16f88. Wieviele "call"s möglich?



kante23
07.12.2007, 16:22
Hallo,
bei einem Programm was ich geschrieben habe, kommt es bei der mplab-simulation zu einem ganz komischen Fehler. Undzwar springt er bei einer Routine beim "return" statt auf den eigentlichen nächsten Befehl auf die Startadresse (also 0x00) zurück. Hab mir überlegt, dass das vlt an zuvielen "Calls" liegen kann und die Rücksprungadresse nun überschrieben wurde. Ist sowas möglich? und wenn ja wieviele "call"s verträgt so ein Pic denn bzw kann er speichern?
Kann das Programm leider nicht posten, da es ein bischen zulang ist (>5 asm-dateien).
Aber vlt könnt ihr mir ja auch so helfen
Grüße Kante

PS: Und gibt es eventuell eine Möglichkeit mir den Adressenstack anzugucken bzw. zu sehen wieviele "calls" er schon gemacht hat?

Mobius
07.12.2007, 21:39
Bei einem PIC16F liegt die Stack-Tiefe bei 8 und ist hardware-maßig, also nicht erweiterbar. Also, nie mehr als 8 rekursive call-aufrufe ausführen.
In Mplab kannst du unter "View" -> "2 Hardware Stack" den aktuellen Stack anschauen.

lg
Mobius

kante23
07.12.2007, 23:45
vielen dank.
8 ist ja garnicht so viel (stimmt aber mit der Zahl überein die ich wonaders schon gelesen hatte). Muss man ja ganz schön aufpassen (bei größeren Programmen). Aber andereseits geht es ja auch so. Hab das Programm mitlerweile abgeändert, da mir die Struktur eh nicht wirklich gefallen hat.
Habs jetzt anders gelöst.
vielen Dank Kante

kante23
09.12.2007, 17:41
Ich hab nochmal über die 8 Stufen des Stakcs nachgedacht. Ist ja wirklich nihct besonders viel (und trägt wahrscheinlich gut dazu bei, das Assemblecode oftmals so unübersichtlich gestalltet ist).
Wie wird das denn von einem C Compiler gelöst (z.B c5xx)
Dort kann man doch unbegrenzt viele Subs aufrufen, oder irre ich mich da?
Grüße Kante

phaidros
10.12.2007, 00:46
Wahrscheinlich über einen Software-Stack.
Geht ungefähr so:
Beim Unterprogramm-Aufruf wird die momentane Adresse (die der Compiler ja kennt) in einem Bereich des RAM abgelegt. Eine andere RAM-Adresse bildet den Index in diesen Bereich und wird um eins erhöht. Jetzt erfolgt der Unterprogramm-Aufruf, aber nicht per CALL sondern per GOTO.

Wenn das Unterprogramm zurückkehren soll, holt es die Adresse aus dem RAM-Bereich (nachdem der Index um 1 verringert wurde) und schreibt diese Adresse in PCL und PCH (den Programm-Zähler). Die Stack-Tiefe ist so nur durch das RAM begrenzt.

Nachteile:
- Ist natürlich langsamer. Vor allem, wenn man auch noch auf Stack-Overflow und Underflow testen will.
- Der Stack ist nicht mehr geschützt. Ein wildgewordener Programmteil kann irgendwelche Sachen in den Stack-Bereich oder den Index-Pointer schreiben und die zurückkehrenden Unterprogramme landen im Nirvana.

PICture
10.12.2007, 03:30
Hallo!

Man kann Unterprogramme (UP), die aus UPs aufgerufen werden, anstatt mit "call", mit "goto" aufrufen. Dazu müss in den UPs "return" mit "goto" ersetzt werden.

Nach der Änderung wird nur eine Rücksprungadresse auf dem Stapel abgelegt und nach der Ausführung vom UP3 wird zurück ins Main direkt nach "call UP1" gesprungen.

Ein Beispiel zur Verdeutlichung ist im Code.

MfG

Main ...........
call UP1
...........
goto Main

UP1 ..........
call UP2
return

UP2 ..........
call UP3
return

UP3 ..........
return

Geänderte UPs:

UP1 ..........
goto UP2

UP2 ..........
goto UP3

UP3 ..........
return

kante23
10.12.2007, 09:59
Und was bringt mir das für einen vorteil?
Versteh das nicht ganz. Beim ersten "main" "verbruach" ich doch nur ein Stack-level und beim zweiten schon 2(erst Call UPX und dann UP1, UP2 ...), oder?
Somit verbruach ich doch eher mehr als das ich etwas einspare???
Vlt kannst du es mir ja nochmal erklären..
gruß Kante

PICture
10.12.2007, 15:31
Hallo kante23!

Sorry! Ich habe es falsch erklärt, nicht so, wie ich das gemeint habe und meinen letzten Beitrag schon korriegiert. Schau ihn, bitte, noch mal an. :)

MfG