mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Datenüberlauf im Stack


Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute!

Ich beschäftige mich gerade mit dem LPC2138 von ARM und hatte gerade
ein kleines Problem mit der Stackgröße.
Der Kontroller stürzte ab oder Variablen änderten plötzlich aus
heiterem Himmel ihre Größe.

Jedenfalls nach der Umstellung: Der Fast-IRQ-Stack wurde von mir von 4
Byte auf 0x20 Bytes angehoben.
Nun funktioniert alles einwandfrei.

Ich habe in meiner Ausbildung gelernt, dass der Stack-Speicher nur
Rücksprungadressen sichert, damit der PC-Counter weiß, an welcher
Stelle er im Hauptprogramm z.B. nach einer IRQ-Routine oder nach der
Ausführung einer Funktion, weitermachen muss.

Nun hörte ich aber, dass der Stack des CARM-Keil-Compilers nicht nur
Rücksprungadressen enthalten soll, sondern auch lokale Variablen.
Wie soll dass denn gehen? Ist das ein Gerücht oder stimmt das?

Meiner Meinung nach ist ein Stack nur ein Stapelspeicher
(FIRST-IN-LAST-OUT), wie soll man auf eine Variable oder auf ein
Variablen-Feld, welche sich im Stack befinden zugreifen, man hat doch
hier keinen direkten Zugriff?!?

Was haltet ihr von der Sache?

Ich freue mich schon auf eure Antworten.

Danke im Voraus.

Tschüss, Martin

Autor: Rainer S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Martin,

Dein Wissen über einen Stack ist nicht vollständig. Es ist richtig,
dass er neben den Rücksprungadressen auch lokale Variablen aber auch
Parameter enthalten kann. So ist es z.B. üblich, dass die
Interrupt-Routine Register, die innerhalb der Interrupt-Routine
verändert werden, sichert und am Ende wiederherstellt. Damit erklärt
sich auch die Auswirkung der Vergrößerung von 4 auf 32 Byte.

Die Bezeichnung für einen Stack alias Stapelspeicher ist eher LIFO
(Last In First Out). Deine Bezeichnung ist allerdings semantisch
korrekt, auch wenn die Bezeichnung nicht üblich ist.

Gruß,
Rainer

Autor: Uwe Große-Wortmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist üblich, einem Unterprogramm über den Stack die Variablen zu
übermittelt, mit denen dieses arbeiten muss. Vor jedem Aufruf werden
also die Daten gemeinsam mit der Rücksprungadresse auf den Stack
gepackt, das Unterprogramm holt sich den ganzen Krempel wieder, macht
seinen Job damit, packt die Ergebnisse wieder auf den Stack und springt
zurück. Dann kann das Hauptprogramm die Ergebnisse auf dem Stack
abholen.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau Dir mal das Assembler-Listing von Deinem Programm an. Du wirst
Dich wundern, wie viele push- und pop-Befehle da auftauchen... Und
genau mit diesen Befehlen hat man nämlich direkten Zugriff auf den
Stack.

Autor: Läubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
direkten zugriff auf den Stack hat man über den Stackpointer... mit push
und pop nur auf das oberste Element...

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Uwe
> Es ist üblich, einem Unterprogramm über den Stack die Variablen zu
übermittelt,

und was wenn beim Einsprung in´s Unterprogramm nen Interrupt auftritt
??
halte ich für keine gute Idee.
Es gibt eeir Leute die vergeben dafür ne rote Karte ..... ;-)

Das sollte man dann doch lieber in den Registern tun. Auf den SP
gehören nur die Returns und die Regitser die im Interrupt geändert
werden.
Mehr nicht.

Autor: Rainer S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stephan: Wieso sollte es mit der Übergabe von Parametern auf dem Stack
in Verbindung mit einem Interrupt Probleme geben? Es spielt keine
Rolle, ob eben eine z.B. eine arithmetische Operation abgearbeitet wird
oder ein Datum auf den Stack gelegt wird. Es ist für die Interrupt
Routine völlig egal, was das Programm macht, das unterbrochen wird.

Gruß,
Rainer

Autor: mh789 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf die Schnelle hab ich mal das ergoogelt:
<http://www.cs.umbc.edu/~chang/cs313.s02/stack.shtml>;. Ich hoffe, das
hilft Martin und Stephan.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> und was wenn beim Einsprung in´s Unterprogramm nen Interrupt
> auftritt ??

Was soll dann sein?
Dann wird, wie sonst auch, dass pushen auf den Stack durch
den Interrupt unterbrochen, der Interrupt abgearbeitet
(der hoffentlich den Stack so hinterlässt wie er ihn vorgefunden
hat), und dort weiter gemacht wo der Interrupt unterbrochen hat:
Beim pushen der Argumente auf den Stack.

> Das sollte man dann doch lieber in den Registern tun.
Geb ich dir grundsätzlich recht. Geht auch schneller.
Nur was hilfts, wenn der Compiler das ganz anders implementiert.

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rainer,
halte ich für keine gute Idee..... schrieb ich. Nicht Probleme.
Die Rede war ja von "Es ist üblich ".

Es ist aber nicht üblich sondern ehr unüblich.
Wer am SP fummelt, sollte schon sehr genau wissen was er da tut.
Und wenn Martin, was ich vermut, noch nicht lange programmiert, dann
sollte man ihm sowas auch nicht noch nahe legen. Er hats ja schließlich
richtig gelernt. Da er warscheinlich kein Assembler macht, hat er
natürlich kaum einen Überblick über die Menge der verwendeten Push´s
und Pop´s.
Schwach das Keil sowas beim Copilieren offensichlich nicht bemerkt

.........oder Martin hat die Meldung ignoriert.

Du kannst ja mit Deinem SP machen was Du willst, ich bleibe bei R0-R7,A
und B und frage ruhig andere Assembler Programmierer, die meisten werden
Dir das gleiche sagen.

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also Leute haut euch.

Die Parameterübergabe über den Stack ist auch sicher, wenn man
Disziplin hält, d.h. genau genau so viel popt, wie gepusht wurde. Ein
C-Compiler hat damit keinerlei Probleme.


Aber in Assembler schludert man gerne mal und dann ist es viel
gefahrloser, wenn man Register nimmt. Es schadet dann überhaupt nichts,
wenn man mehr Werte übergibt, als abgeholt werden.


Und wenn man mehrere Register hat, dann ist natürlich die
Parameterübergabe über Register schneller und Code sparender.
Deshalb pushen Compiler für Registerarchitekturen (AVR, 8051) eher
selten.


Peter

Autor: Stephan Henning (stephan-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HIER wird nicht gehaun !!!
Bin sehr sensibel...... war 45 verschüttet...... :-)

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.