mikrocontroller.net

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


Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein

Autor: Jan (Gast)
Datum:

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

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Alexander (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas O. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas O. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht 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.

...

Autor: Thomas O. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
werds mir mal anschauen.

Autor: Swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, bei der Nutzung im Programm sind beide Möglichkeiten gleich.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht 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.

...

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.