Forum: Mikrocontroller und Digitale Elektronik Stack vs. RAM beim Mega8


von Jan (Gast)


Lesenswert?

... kurze, hoffentlich nicht zu dumme Frage:

Ich definiere im RAM meines Mega8 einige (so ca. 40) Speicherstellen
z.B.
.equ Pot1VAL = 0x0060+0
.equ Pot2VAL = 0x0060+1
...
um sie im Hauptprogramm mit STS / LDS anzusprechen.

Danach initialisiere ich wie gewohnt den Stackpointer

ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp

Kann ich hierbei sicher gehen, dass sich die Speicherbereiche nicht
"überschneiden" , also dass mit den darin gespeicherten Werten nichts
schief geht? Bitte nicht zu sehr lachen ;-)

Jan

von A.K. (Gast)


Lesenswert?

nein

von Jan (Gast)


Lesenswert?

... muß /kann ich dann den Stackpointer an einer höheren Speicherstelle
initialisieren?

von A.K. (Gast)


Lesenswert?

Höher geht nicht, da ist nichts mehr, und es ändert nichts am Problem.
Du musst sicherstellen, dass der Stack nicht mehr als RAM-40 Bytes
verbrät. Programmfehler mal ausnommen, ist ein Konflikt freilich arg
unwahrscheinlich, zumal Assembler-Programme nicht zu exzessivem
Stack-Konsum neigen.

von Jan (Gast)


Lesenswert?

... also werde ich sicherheitshalber noch mal zählen. Prinzipiell
spricht wohl somit nichts gegen die von mir favorisierte Methode
Speicherplätze zu benutzen, wenn nicht genug Register da sind ...

Vielen Dank soweit!

von crazy horse (Gast)


Lesenswert?

ne, ist schon richtig. Und deswegen fängt man mit den Variablen unten,
mit dem stack oben an, das gibt max. Nutzung. Treffen sie sich dennoch,
musst du entweder dein Programm optimieren (temporäre Variablen, overlay
bzw. die Stackbelastung geringer halten (Unterprogramme, ISR,
Parameterübergabe, push/pop usw.)
Reicht das alles nicht -> MC mit zu wenig RAM gewählt :-)

von Alexander (Gast)


Lesenswert?

Kann man eigentlich rausfinden, ob der Speicher reicht. Oder sieht man
das einfach daran, daß das Programm nicht mehr richtig läuft? Also ich
denke mal, daß der Compiler das nicht abchecken kann. Wie würde man
dann manuell eine Warnung ausgeben, wenn der Ram voll ist?

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Das mit der Speicherreservierung kannst du übrigens etwas vereinfachen:

.dseg
Pot1VAL:          .byte  1
Pot2VAL:          .byte  1
ganz_viel_text:   .byte 20

Statt "0x1234" kannst du nun direkt "Pot1VAL" usw. als Adresse
verwenden, ohne selber herumrechnen zu müssen.

von Stefan K. (_sk_)


Lesenswert?

> Kann man eigentlich rausfinden, ob der Speicher reicht.

Ans obere Ende der Variablen ein paar Dummy-Variablen legen und
initialisieren. Wenn die Werte überschrieben wurden, war der böse Stack
da ...

> Wie würde man dann manuell eine Warnung ausgeben, wenn der Ram voll
> ist?

Die Frage ist: wieviel kann man dem System noch vertrauen, nachdem ein
Stack-Überlauf aufgetreten war? Die Brute-Force Methode ist: auf
Überlauf testen und ggf. in eine Endlos-Schleife gehen. Während dem
Debuggen findet man den Fehler dann leicht. Beim Endprodukt hat man
sicher eine Watchdog drin, die dann zuschlagen kann.

Gruß, Stefan

von Thomas O. (Gast)


Lesenswert?

@Andreas Schwarz: Wollte mal kurz fragen wie das mit den DSEG beim
Programmieren abläuft, werden die Daten mit ins Flash geschrieben und
beim Starten des Programms immer ins SRAM kopiert?

Nehme mal stark an das die Daten der Variablen dann automatisch ans
andere Ende im SRAM abgelegt werden.

von A.K. (Gast)


Lesenswert?

"dseg" erlaubt dir, die Variablen zu plazieren. Das war's dann aber
auch. Irgendwelche Initialisierungen sind dein Problem, der
Anfangsinhalt ist vom Zufall bestimmt.

von Thomas O. (Gast)


Lesenswert?

ok Anfangsinhalt ist ungewiss,weil ja noch nichts drinsteht. Mit
platzieren meinst du warscheinlich die Reihenfolge, aber da ich ja die
Variablen ansprechen kann spielt es ja für mich keine Rolle wierum sie
sortiert sind hauptsache weit weg vom Stack.

von Hannes L. (hannes)


Lesenswert?

Mit "platzieren" ist die Zuordnung zu Adressen gemeint.

Mit .org legt man die erste zu benutzende Adresse fest.
Mit dem Label legt man den Namen der Variable fest.
Mit .byte oder .word legt man die Anzahl der benötigten Zellen fest.

Man erreicht damit nur eine korrekte Zuordnung von Namen (Labels) und
Adressen. Die Werte (Inhalte) musst du schon selbst initialisieren.

Hangele dich mal im Help-Menü des AVR-Studios bis zum ACR-Assembler
oder AVR-Assembler2 durch (jenachdem, welchen du zum Assemblieren
benutzt), da gibt es mehr Informationen zu den ASM-Direktiven.

...

von Thomas O. (Gast)


Lesenswert?

werds mir mal anschauen.

von Swen (Gast)


Lesenswert?

@Andreas:

Die Möglichkeiten

.equ Pot1VAL = 0x0060+0

und

.dseg
Pot1VAL:          .byte  1

können doch beide im Programm gleich angesprochen (z.B. STS) werden?
Nur die Anordnung ist im zweiten Fall einfacher, da automatisch?

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Ja, bei der Nutzung im Programm sind beide Möglichkeiten gleich.

von Hannes L. (hannes)


Lesenswert?

@Thomas:
Mach dich mal mit dem Stack und dem "Stackverbrauch" deiner Programme
vertraut, dann wirst du sehen, dass deine Angst unbegründet ist.

Jeder Interrupt braucht zwei Bytes Stack zum Aufruf und evtl. je ein
weiteres Bytes für Push & Pop. Diese sind aber nur "geborgt" und
werden zum Ende der ISR zurückgegeben.

Jedes RCALL/CALL braucht zwei Bytes Stack, die beim RET zurückgegeben
werden. Dazu kommt je ein Byte für eventuelles Push/Pop.

Bis dahin ist der Stackbedarf überschaubar. Etwas aufpassen musst du
allerdings, wenn du aus einem Unterprogramm ein weiteres Unterprogramm
aufrufst und aus diesem ein weiteres Up. Dann addiert sich der
jeweilige Stackbedarf, wird aber beim Verlassen der UPs wieder
freigegeben.

Übrigens ist es oberstes Gebot, dass der Stack "ausgeglichen" ist.
Also jeder Interrupt oder UP-Aufruf (Call, Rcall) braucht definitiv
seinen Rücksprung (Ret, Reti) und jedes Push braucht sein Pop.
Ansonsten wächst der Stack und überschreibt dir zuerst das SRAM, dann
den I/O-Bereich und zu guter Letzt auch die Register.

...

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
Noch kein Account? Hier anmelden.