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
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
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.
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.
direkten zugriff auf den Stack hat man über den Stackpointer... mit push und pop nur auf das oberste Element...
@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.
@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
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.
> 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.
@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.
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
HIER wird nicht gehaun !!! Bin sehr sensibel...... war 45 verschüttet...... :-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.