Forum: Mikrocontroller und Digitale Elektronik ATmega32 CALL ohne SP vorher


von Denis M. (fusselbaum)


Lesenswert?

Hi Leute,

was passiert eigentlich, wenn ich mit CALL in ein Unterprogram
springe, ohne vorher den Stackpointer gesetzt zu haben?
Würde er dann in das letzte RET springen, dass ich gesetzt habe?
Was ist wenn ich noch kein SP verwendet habe?
LG

von Peter II (Gast)


Lesenswert?

Denis Meißner schrieb:
> was passiert eigentlich, wenn ich mit CALL in ein Unterprogram
> springe, ohne vorher den Stackpointer gesetzt zu haben?

auch ohne setzen, hat der SP irgendeinen wert. Mit diesem wird dann halt 
gearbeitet.

von holger (Gast)


Lesenswert?

>was passiert eigentlich, wenn ich mit CALL in ein Unterprogram
>springe, ohne vorher den Stackpointer gesetzt zu haben?

Probiers im Simulator aus. Altenativ könntest du statt deine
Zeit zu verschwenden auch gleich den Stackpointer setzen.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Denis Meißner schrieb:
> was passiert eigentlich, wenn ich mit CALL in ein Unterprogram
> springe, ohne vorher den Stackpointer gesetzt zu haben?

Er wird korrekt ins Unterprogramm springen, egal, ob du den SP 
initialisiert hast oder nicht.

> Würde er dann in das letzte RET springen, dass ich gesetzt habe?

Die Frage verstehe ich nicht. Du meinst, was passiert, wenn das per CALL 
gestartete Unterprogramm mit RET beendet wird?

Falls der SP vorher nicht initialisiert wurde, wird der Programmablauf 
mit einiger Sicherheit an einer Stelle fortgesetzt, an der du es gar 
nicht haben willst. Anders ausgedrückt: das Programm stürzt 
wahrscheinlich ab.

Es bleibt die Frage, warum du den SP nicht initialisieren magst.
Gerade bei dem technisch schon länger nicht mehr aktuellen ATmega32 ist 
das wichtig, weil der SP sonst den Wert 0 hat. Du könntest natürlich 
auch den Nachfolger des Nachfolgers des ATmega32 verwenden: den 
ATmega324A.
Beim ATmega324A wird der SP nämlich automatisch mit dem richtigen Wert 
initialisiert, so dass du dich im Normalfall nicht darum kümmern musst. 
Zu empfehlen ist die explizite Initialisierung aber trotzdem, weil es ja 
sein kann, dass der Controller per Reset oder Brown-out neu gestartet 
wird.

Grundsätzlich kannst du natürlich auch ganz ohne SP arbeiten. Dann 
solltest du allerdings Assembler als Programmiersprache verwenden und 
ein paar Besonderheiten berücksichtigen...

von Stephan B. (matrixstorm)


Lesenswert?

Hi.

Der SP wird bereits durch die Hardware nach einer RESET-Condition auf 
RAMEND gesetzt. (Ich weis, die glibc macht es danach nocheinmal in 
Software...)

Wenn du also nicht absichtlich den SP vorher verschoben hast, passiert 
absolut nichts (selbst wenn du mittels "naked" in "init0" starten 
wuerdest), weil alles wie gewohnt ablaueft.

MfG

von holger (Gast)


Lesenswert?

>Der SP wird bereits durch die Hardware nach einer RESET-Condition auf
>RAMEND gesetzt.

Nicht beim Atmega32.

von Stephan B. (matrixstorm)


Lesenswert?

Okay, habe eben nocheinmal nachgelesen. Stimmt!
Beim ATmega32 ist SP initial undefiniert.

In diesem Fall droht ein Unterprogrammaufruf unkontrolliert verwendete 
Variablen (oder sogar Register?) zu ueberschreiben.

MfG

von der alte Hanns (Gast)


Lesenswert?

What else is there to do on a sunday-afternoon, when your girl-friend 
has left you, your tv-set is broken and your jogging-suit is in the 
wash.

von Peter D. (peda)


Lesenswert?

Stephan B. schrieb:
> Beim ATmega32 ist SP initial undefiniert.

Nein, er ist 0.
Ein Call würde also die Returnadresse in R0 und 0xFFFF speichern wollen.
Die Register können zwar als SRAM adressiert werden, nicht jedoch als 
Stack.

Es ist also nicht der Stackpointer undefiniert, sondern der SRAM, auf 
den er zeigt.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Stephan B. schrieb:
> In diesem Fall droht ein Unterprogrammaufruf unkontrolliert verwendete
> Variablen (oder sogar Register?) zu ueberschreiben.

Variablen werden erst nach mehreren verschachtelten Aufrufen 
überschrieben. So schnell schafft es der SP nicht von 0 aus (nach unten) 
ins SRAM.
Register werden nach meiner Erinnerung nicht überschrieben, weil diese 
Adressierungsart (gemappte Register) für den SP HW-technisch nicht 
implementiert wurde.

In Assembler ist es locker möglich, mit Unterprogrammen zu arbeiten 
(z.B. nur eine Ebene), ohne den Stack zu verwenden. Es muss ja nicht das 
klassische RCALL und RET sein. Sogar Interrupts sind dann möglich - 
sofern man eine feste Rücksprungstelle verwendet.
Das ist natürlich nur für spezielle Fälle sinnvoll, wenn man z.B. das 
gesamte SRAM für Variablen oder einen Puffer benötigt. Über seine 
Beweggründe hat Denis Meißner aber leider nichts verraten...

von Stephan B. (matrixstorm)


Lesenswert?

Peter Dannegger schrieb:
> Nein, er ist 0.

Davon steht nichts im Datenblatt (soweit wie ich ueberflogen habe) und 
ich halte das auch fuer ein Geruecht.

Der SP ist vielleicht NULL beim PowerUp, aber nach einem Reset wird der 
letzte Wert darin stehen - also undefiniert im weitem Sinne.

MfG

von Spess53 (Gast)


Lesenswert?

Hi

>Davon steht nichts im Datenblatt (soweit wie ich ueberflogen habe) und
>ich halte das auch fuer ein Geruecht.

Dann lies mal S.12 im aktuellen Datenblatt.

MfG Spess

von Stephan B. (matrixstorm)


Lesenswert?

Unten bei "Initial Value"?

Okay, obwohl ich das wohl nicht glaube g ( ;-) ) ist es wohl nicht 
verkehrt das anzunehmen.

Also Danke fuer die Richtigstellung, ich bin von den XMegas verdorben 
worden ;-)

MfG

von Spess53 (Gast)


Lesenswert?

Hi

Was gibt es da nicht zu glauben?

Datenblatt S.36:

Resetting the AVR

During Reset, all I/O Registers are set to their initial values, and the 
program starts execution from the Reset Vector.

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.