mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Was ist der Stack genau...?


Autor: A. Arndt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

kann mir jemand die Funktion der Stack-Tiefe bei FASTAVR erklären, was
trägt man warum hier ein, ich denke, es ist Reservierung im RAM für
Variablen, aber warum steht dieser meist bei 32 bei z.B. Mega und nicht
auf z.B. 128, ich habe jetzt komische Fehler beim Umgang mit Variablen,
die Erhöhung des Stack-Wertes soll helfen...

Gruss
A. Arndt

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann zu FASTAVR nicht wirklich was sagen, aber mal allgemein zum Stack:
Wenn du ein Unterprogramm aufrufst, dann muss der µC sich merken, wo er
danach wieder zurückspringen muss. Also wird auf den "Stack", zu
deutsch "Stapel", die Rücksprungadresse gelegt. Lokale Variablen
werten ebenso auf den Stack gelegt und dort verwendet. Wenn das
Unterprogramm beendet ist, werden alle lokalen Variablen wieder vom
Stapel genommen (ihr Gültigkeitsbereich ist hiermit beendet), die
Rücksprungadresse wird gelesen und angesprungen, das Unterprogramm ist
hiermit beendet.
Wenn du viele lokale Variablen oder viele verschachtelte Aufrufe hast,
kann es sein, dass der Stack stark anwächst. Wie gesagt: Ich weiss
jetzt nicht, was 32 oder 128 bei "Stacktiefe" bedeuten soll, aber
wenn das die Anzahl der Worte ist, die der Stack fassen kann, dann
sollte schnell klar werden, dass man mit den Ressourcen sparsam umgehen
soll und evtl. globale Variablen benutzen sollte, wenn dies angebracht
ist und Speicher sparen kann, oder eben die Stack-Größe erweitern.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wichtig wäre noch, dass der stack von oben nach unten wächst - also vom
ram ende aus. wenn er zu gross wird kann er andere sachen im ram
überschreiben (globale variablen etc.)
probleme kann es halt bei vielen verschachtelten funktionsaufrufen mit
vielen/grossen parametern kommen oder rekursionen usw..

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ersteinmal soll der Stack nur so gross wie nötig sein, um nicht unnötig
RAM zu blockieren, der Platz fehlt sonst evtl. für Variablen.
Aber das Problem liegt daran, zu erkennen, wie gross der Stack denn nun
wirklich sein muss, dass kann kein Compiler erkennen. Ein Stack-Überlauf
führt normalerweise zum Absturz und kann von üblichen MCs auch nicht
erkannt werden.
In erster Linie belasten Funktionsaufrufe und Interrupts den Stack, bei
Funktionsaufrufen wird zumindest die Rückkehradresse, manchmal auch die
Parameterübergabe über den Stack realisiert, meist wird dazu jedoch ein
gesonderter Datenstack benutzt. Interruptroutinen sind im Prinzip ja
auch Funktionsaufrufe, nur dass man vorher nicht weiss, wann diese
Funktionen aufgerufen werden, also immer mit dem schlimmsten
rechnen...
Kritisch wirds dann, wenn Funktionen mehrfach  wieder andere Funktionen
(oder sich selbst, Rekursion) aufrufen und als i-Tüpfelchen dann noch
ein Int draufknallt.
Der Stacküberlauf überschreibt gnadenlos Variablen, was dann passiert,
kannst du dir selbst vorstellen.
Für den Test kann man sich Stack-end-marker setzen und dann versuchen
in einer Simulation den kritischsten Systemzustand zu erreichen und den
dann erreichten Stackwert als Stackgrösse zu setzen.
Reicht der RAM nicht, diese Bedingung zu erfüllen, muss das Programm
korrigiert werden (Verschachtelungstiefe reduzieren, in kritischen
Fällen die Interrupts sperren).

Autor: Christof Krüger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und um es komplett zu machen: Der so genannte "Heap" wächst von unten
nach oben (also von kleinen Speicheradressen zu hohen). Im Heap werden
globale Variablen und dynamisch alokkierter Speicher abgelegt. Entweder
gibt es eine feste Grenze und wenn der Heap oder Stack über diese Grenze
wachsen möchte gibt es einen Heap- resp. Stackoverflow, oder aber die
Grenze ist fließend und das große "Bumm" gibt es, wenn Stack auf Heap
treffen.
Da ich kein Basic (mehr) kann, hier ein Beispiel aus der c-Sprache.
Wird z.B. einer Funktion eine große struct übergeben, dann wird sie
ganz auf den Stack kopiert. Du kannst in deiner Funktion dann darauf
schreiben, wie du lustig bist, ohne den eigentlich übergebenen struct
zu ändern, da du ja auf einer Kopie arbeitest. Wenn du den struct aber
eh nicht änderst, sondern nur ausliest, dann hast du eine unnötige
Kopie gemacht und hättest stattdessen einen Pointer oder eine Referenz
auf das struct übergeben sollen.
Bei Basic gibt es auch eine Entsprechung zu struct, war das record? Und
als Referenz kann man sowas wohl auch übergeben (by ref?).

Autor: A. Arndt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

vielen Dank für Eure Antworten, ich arbeite zwar "nur" mit dem
einfachen Basic, aber ich denke, ich habe verstanden, was Ihr meint...


Gruss
A. Arndt

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.