Atmega8, AVR-Studio 4, Simulator2 Viele Beispielprogramme im AVR-Tutorial fangen mit der Initialisierung des Stackpointers an: ******************** .CSEG .org 0 ldi r16, low(RAMEND) ; Stackpointer initialisieren out SPL, r16 ldi r16, high(RAMEND) out SPH, r16 ************* Viele Programmbeispiele - z.B. die Beispiele aus dem Kapitel EEPROM verwenden doch garkeinen Stack, SPH und SPL werden garnicht dort verwendet etc., warum wird das dennoch gemacht? Ich setze nun die Adresse im Stackpointer auf RAMEND - wozu?
Ich hab mit AVR nicht viel am hut. Ich kenn auch nicht das tutorial. Der Stack wird für Funktionsaufrufe verwendet. Springst du in eine Funktion muss irgendwo gesichert werden, was vorher in den Registern stand, und wo du her kommst. damit der return dann ach wieder richtig springt. Der Stack wird in den Hochsprache für variablen innerhalb einer Funktion verwendet. und der stack wächst bei vielen systemen von oben nach unten. daher ramend.
PC-Anfaenger schrieb: > Ich setze nun die > Adresse im Stackpointer auf RAMEND - wozu? Damit Bytes an definierte Stellen auf Stack gelegt werden können und Dir nicht die Register, den I/O-Bereich oder andere SRAM-Bereiche mit ungewollten falschen Werten füllen. Schau mal in der Befehlsübersicht nach, welche Befehle den Stack benutzen. Wenn Du ohne Stackpointer auskommen willst, dann solltest Du einen AT90S1200, Tiny11, Tiny12 oder Tiny15 benutzen. ...
Jeder call-Befehl und jeder Interrupt schreibt auf den Stack, damit der ret-Befehl dort die Rücksprungadresse findet. Somit benutzen nur die allereinfachsten Beispielprogramme den Stack nicht - diejenigen nämlich, die ohne Subroutinen und Interrupts auskommen.
PC-Anfaenger schrieb: > Viele Programmbeispiele - z.B. die Beispiele aus dem Kapitel EEPROM > verwenden doch garkeinen Stack, SPH und SPL werden garnicht dort > verwendet etc., warum wird das dennoch gemacht? Weil es nur ein paar Takte sind, die beim Programmstart benötigt werden und dann muss man bei Programmerweiterungen, die einen Stack benötigen nicht daran denken, dass man noch einen Stackpointer einrichten muss. So was nennt man "defensives Programmieren" - mit einplanen, daß ein Programmierer auch mal Fehler machen wird und gleich vorausplanen, so dass solche Fehler nicht gleich zum Desaster ausarten. > Ich setze nun die > Adresse im Stackpointer auf RAMEND - wozu? Weil der Stack vom Ende des Speichers nach vorne wächst, so man einen verwendet.
PC-Anfaenger schrieb: > Viele Programmbeispiele - z.B. die Beispiele aus dem Kapitel EEPROM > verwenden doch garkeinen Stack, SPH und SPL werden garnicht dort > verwendet etc., warum wird das dennoch gemacht? Jedes dieser Beispiele enthält Unterprogrammaufrufe oder Interrupthand- ler. Bei beiden wird die Rücksprungadresse auf den Stack gelegt, weswe- gen dieser richtig initialisiert sein sollte.
Florian schrieb: > Ich dachte immer, dass man sich das bei den neueren AVRs Sparen kann? Theoretisch ja, da als Initial Value bereits der richtige Wert (RAMEND) drinsteht. Das gilt jedoch nur für die neueren Chips, daher ist es kein Schaden, es einfach generell zu machen (kostet 4 Assemblerbefehle zu Programmbeginn). :-)
Hi >Wenn Du ohne Stackpointer auskommen willst, dann solltest Du einen >AT90S1200, Tiny11, Tiny12 oder Tiny15 benutzen. Ohne Stackpointer, ja. Aber nicht ohne Stack. >Viele Programmbeispiele - z.B. die Beispiele aus dem Kapitel EEPROM >verwenden doch garkeinen Stack, SPH und SPL werden garnicht dort >verwendet etc., warum wird das dennoch gemacht? Ich setze nun die >Adresse im Stackpointer auf RAMEND - wozu? Der Stackpointer wird, ohne das du ihn direkt ansprichst, von 'call', 'rcall', 'ret', 'push', 'pop, 'reti' und Interrupts (was vergessen?) benutzt. Diese Befehle legen Werte auf der Adresse, auf die der Stackpointer zeigt, ab und decrementieren den Stackpointer oder incrementieren den Stackpointer und holen den Wert, auf den der Stackpointer zeigt. Bei einem 'call' wird zum Beispiel die Programmadresse des Befehls nach dem 'call' auf dem Stack gespeichert. Bei einem 'ret' wird der Programmcounter wieder mit diesem Wert geladen und das Programm macht nach dem Call-Befehl weiter. MfG Spess
Vielen Dank fuer die Vielzahl von Antworten. Betrachte ich einfach mal die Befehle push und pop. Wenn ich also vor dem Aufruf einer Routine einen Register sichern will und schribe push r16 Dann müsste ja - wenn ich den Zeiger zum Ende auf RAMEND lege, bei Speichervorgängen der Zähler dekrementiert werden - weil wenn ich ja bereits bei RAMEND bin, dann kann ja nichts weiter inkrementiert werden? Was ist aber, wenn ich den Stack nicht initialisiere? Wenn der dann bei "RAMSTART" stehen würde und ich dann etwas speichern würde - und dann dekrementieren täte - so dürfte das ja dann nicht gehen? Also würde es bedeuten, wenn ich nicht die oben vorgestellte Initialisierung mache und selber mit .dseg Speicher reserviere, dass es dann zu Ueberschneidungen kommt, wenn ich push/pops und andere Spruenge mache?
Hi >Dann müsste ja - wenn ich den Zeiger zum Ende auf RAMEND lege, bei >Speichervorgängen der Zähler dekrementiert werden - weil wenn ich ja >bereits bei RAMEND bin, dann kann ja nichts weiter inkrementiert werden? Wird er auch. Aus dem Instruction Set: This instruction stores the contents of register Rr on the STACK. The Stack Pointer is post-decremented by 1 after the PUSH. ^^^^^^^^^^^^^^^^ >Was ist aber, wenn ich den Stack nicht initialisiere? Wenn der dann bei >"RAMSTART" stehen würde und ich dann etwas speichern würde - und dann >dekrementieren täte - so dürfte das ja dann nicht gehen? Nicht initialisiert zeigt der Stackpointer, je nach AVR, entweder auf $0000 oder RAMEND. >Also würde es bedeuten, wenn ich nicht die oben vorgestellte >Initialisierung mache und selber mit .dseg Speicher reserviere, dass es >dann zu Ueberschneidungen kommt, wenn ich push/pops und andere Spruenge >mache? Richtig. Und das endet zu 100% in einem Crash. 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.