stationeers.de Mod-Werkstatt · Dominik1199
EN Anmelden
  1. Start
  2. IC10-Akademie
  3. Tag 124

Tag 124 von 365 · Fortgeschritten · Monat 5: Speicher und Struktur

Stack-Fallen

Ein vergessenes pop füllt den Stack Takt für Takt bis zum StackOverFlow. Dazu kommen ein überschriebenes sp und Speicherinhalte, die einen Neustart überleben.

Lektion 14 Min. Woche 18

Das lernst du heute

  • StackOverFlow und StackUnderFlow
  • sp versehentlich überschreiben
  • Speicher beim Neustart

Ein Chip läuft seit Stunden einwandfrei, dann steht er plötzlich mit StackOverFlow. Niemand hat etwas geändert. Der Fehler war von Anfang an im Code, er brauchte nur 512 Takte, um sichtbar zu werden.

StackOverFlow und StackUnderFlow

FehlerUrsache
StackOverFlowpush bei sp = 512 oder eine Adresse über 511
StackUnderFlowpop oder peek bei sp = 0 oder eine negative Adresse

Der klassische Fall: Ein Durchlauf legt drei Werte auf den Stack, holt aber nur zwei herunter. In jedem Takt wächst sp um eins. Nach gut 500 Takten, also gut vier Minuten, ist der Stack voll.

push a
push b
push c
pop x
pop y          # das dritte pop fehlt: sp waechst jeden Takt

Die Regel: In jedem Durchlauf gleich viele pop wie push. Wer unsicher ist, setzt am Anfang der Hauptschleife move sp 0. Dann beginnt jeder Durchlauf mit leerem Stapel, auch wenn irgendwo ein pop fehlt.

sp versehentlich überschreiben

sp ist ein ganz normales Register, Nummer 16. Jeder Befehl, der hineinschreibt, verschiebt den Stapel: move sp 7, add sp sp 1, ein alias auf r16. Danach liest pop von einer falschen Stelle, ohne Fehlermeldung. Ein Registerplan mit alias nur für r0 bis r15 schützt davor.

Speicher beim Neustart

Im Spielcode setzt das Aufspielen von neuem Code und das Umstecken des Chips nur sp und die Programmzeile auf 0. Register und Stack-Inhalte bleiben stehen. Auch im Spielstand werden sie gespeichert.

Für den Stack heißt das: Nach einem Neustart steht sp auf 0, aber in den Adressen liegen noch die alten Werte. Eine Tabelle, die du mit poke füllst, ist danach sofort wieder da. Ein Zähler, den du in einer Adresse führst, läuft mit dem alten Wert weiter. Willst du sauber anfangen, löschst du vor dem Start-Label mit clr db.

Achtung

Der Simulator dieser Seite beginnt jeden Test mit leerem Stack und Nullen in allen Registern. Ein Fehler, der nur mit alten Werten auftritt, zeigt sich deshalb erst im Spiel.

Tipp

Ein Überlauf nach Stunden lässt sich im Simulator schnell finden: Tempo auf „Vollgas“ und den Stapelzeiger im Auge behalten. Wächst sp von Takt zu Takt, fehlt irgendwo ein pop.

Schaubild

Der Stack mit Stapelzeiger Platz 0 10 Platz 1 20 Platz 2 30 Platz 3 Platz 4 sp = 3 nächster freier Platz push 40 pop r0 r0 = 30 zuletzt rein, zuerst raus
Jeder push braucht ein pop. Fehlt eins, wächst sp in jedem Durchlauf um eins, bis 512 erreicht sind.

Übung

Aufgabe

Der Chip im Editor sucht die höchste Temperatur der Gassensoren „Nord“, „Mitte“ und „Sued“ über den Stack. Er hat einen Fehler, der ihn nach einiger Zeit mit StackOverFlow anhält, und er übersieht dabei einen Sensor.

  • Finde und behebe den Fehler, sodass jeder Durchlauf den Stack wieder leer hinterlässt (sp = 0).
  • LED „Hoechst“ zeigt die höchste der drei Temperaturen in °C.
  • Fehlt ein Sensor, zeigt die Anzeige −999.

Hinweise

Hinweis 1

Zähl die push und die pop in einem Durchlauf.

Hinweis 2

Das fehlende pop holt den Wert von „Nord“ – danach noch ein max.

Hinweis 3

max mit NaN ergibt NaN. Ein snan auf das Ergebnis reicht für die −999.

Quiz

4 Fragen. Ab 60 % ist das Quiz bestanden – die Auswertung macht der Server.

Tag abschließen

  • Übung im Simulator bestanden
  • Quiz mit mindestens 60 % bestanden

Ohne Konto wird der Fortschritt nur in diesem Browser gespeichert.

Fehler in dieser Lektion melden

Zum Melden bitte anmelden. Anmelden

Esc
↑ ↓ wählenEnter öffnen/ öffnet die Suche überall