www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Warum macht man das?


Autor: Axel Hermann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

bin gerade am Assembler lernen... habe folgende Zeilen noch nicht 
kapiert.
was ist "RAMED" (oder "FLASHED") und was ist SPL - SPH.

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

Das was ich bis jetzt mit LEDs so getestet habe, hat bis jetzt immer 
ohne diese Zeilen Funktioniert...

Achso, bevor ichs vergess .. ich Programiere Mit ATMEL (ATMega8).

Gruß
Axl

Autor: dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
google mal nach stackpointer

Autor: meiner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mit diesen zeilen legst du stack an. ist u.a. notwendig für sprünge oder 
interrupts in deinem programm...

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RAM = RAM-Speicher
END = Ende von irgendetwas
RAMEND = Letzte Adresse RAM-Speicher

SP = Stackpointer

LOW = untere 8 Bit eines 16 Bit Wertes
HIGH = obere 8 Bit eines 16 Bit Wertes

SPL = Hardware-Register des Stackpointers, niederwertiges Byte
SPH = Hardware-Register des Stackpointers, höherwertiges Byte

Was macht der Code? Ganz einfach: Den Stackpointer auf die letzte 
RAM-Adresse initialisieren. Warum die letzte Adresse? Weil der Stack bei 
den AVRs, wie bei fast allen Prozessoren, nach unten wächst.

Autor: Christoph Kessler (db1uq) (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
für jedes aufgerufene Unterprogamm wird die Rücksprungadresse des 
aufrufenden Programms auf den Stack abgelegt und der Stackpointer um 
eine Adresse nach vorn geändert.
Der Stack wächst also vom Ende des Rams nach vorn und kann je nach 
benutzter Tiefe mit dort abgelegten Variablen in Konflikt kommen. Es 
gibt keine automatischen Schutzmechanismen dagegen, der Programmierer 
muß selbst ausrechnen, wieviel Platz der Stack maximal belegt. 
Unterprogramme, Interrupts und push-Befehle verändern den Stack.
Wenn im untersten Unterprogramm mit gepushten Variablen noch ein 
Interrupt auftritt, wird die maximale Ausdehnung erreicht.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Damit...

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

...initialisierst Du den Stack, indem Du den Stackpointer (16-Bit 
I/O-Register SPH:SPL) auf die letzte SRAM-Addresse des Controllers setzt 
(beim ATmega8 = 0x4FF).  Das muss man einmal beim Programmstart machen, 
wenn man Unterprogramme oder Interrupts oder die Befehle 'push' und 
'pop' zum SIchern von Registerinhalten verwenden will, also praktisch 
immer.

Die Konstanten 'RAMEND', 'SPL' und 'SPH' sind wie alle Konstanten in der 
Datei M8DEF.INC definiert, die Du in Dein Programm mittels "include" 
einbindest.  Tipp: M8DEF.INC Mal in einen Editor laden und studieren.

Weitere Infos zum Stack und Stackpointer findest Du - wie immer - im 
Datenblatt des Controllers (hier Kapitel "AVR CPU Core").

Autor: Der Stack (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm sind das HIGH(RAMEND), LOW(RAMEND) konstanten, die irgendwo 
initialisiert sind (wo möglich eine datei), abhängig vom in diesem fall 
RAM des jeweiligen µC ?

bei mir im MSP430 heisst es:

 mov.w   #300h,SP                ; Initialize stack pointe


ich nehme an hier ist es nicht so schön programmiert, da nach 300h -> 
768d push's sense ist oder?

mfg

Autor: Paul Baumann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das holt sich der Kompiler aus der jeweiligen Include-Datei. Die kannst 
Du
auch mit einem Texteditor angucken, dann siehst Du, welche Adressen das
jeweils sind.

Sinn der Sache ist, den Stack vor den Daten im RAM zu "schützen". Der 
Stack
wächst sozusagen von der "Decke" zum "Fußboden" des RAM. Du bist aber 
mit Deinen Daten, die Dein Programm erzeugt auch im RAM, kommst 
allerdings
"von unten hoch".

Irgendwann würdest Du sonst dann (wenn genügend Zeug von Dir in den RAM 
getan worden ist) von unten am Stack "kratzen" und damit dort abgelegte 
Sprungadressen kaputtmachen.

MfG Paul

Autor: max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
|____________________| FFFF
| DATEN              |
|____________________| FFFE
| DATEN              |
|____________________| FFFD
        .
        .
        .
|____________________| 0301
| STACK              |
|____________________| 0300
| STACK              | 02FF
|____________________|
        .
        .
        .

du meinst also das bild hier , nicht?
jop, bei mir würde die daten irrgendwann den stack verschlingen ^^

Autor: Jadeclaw Dinosaur (jadeclaw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo Stack und Daten abngelegt werden, hängt auch von der verwendeten 
Controllerfamilie ab. Grundsätzlich sollte der Stack aber an die höchste 
der zur Verfügung stehenden SRAM-Adressen angelegt werden. Es sei denn, 
der Hersteller gibt ausdrücklich etwas anderes vor. Das es beim MSP430 
mit einem Befehl geht, der AVR derer 4 braucht, liegt zum einen an der 
Tatsache, daß der AVR nach einer anderen Architektur aufgebaut ist, zum 
anderen daran, daß sich Register beim AVR nur 8-Bit-weise laden lassen.

Übrigens, LOW() und HIGH() sind Spezialkommandos des AVR-Assemblers, die 
man in ähnlicher Form auch bei anderen Assemblern findet.

Gruß
Jadeclaw.

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
max wrote:
> |____________________| FFFF
> | DATEN              |
> |____________________| FFFE
> | DATEN              |
> |____________________| FFFD
>         .
>         .
>         .
> |____________________| 0301
> | STACK              |
> |____________________| 0300
> | STACK              | 02FF
> |____________________|
>         .
>         .
>         .
>
> du meinst also das bild hier , nicht?
> jop, bei mir würde die daten irrgendwann den stack verschlingen ^^

Naja, ich würde mal eher so sagen:

 |____________________| 0000
 | DATEN              |
 |____________________| 0001
 | DATEN              |
 |____________________| 0002
         \/
          .
          .
          .
         /\
 |____________________| FFFD
 | STACK              |
 |____________________| FFFE
 | STACK              |
 |____________________| FFFF (bzw. letzte RAM Adresse)


Und der Vollständigkeit halber sei noch gesagt, dass bei den PICs der 
Stack einen eigenen Speicherbereich belegt. Er hat dort die Breite des 
Programcounters, also 12, 14 oder 16 Bit. Bei den 16F Typen ist der 
Stack allerdings nur 8 Ebenen tief und es gibt keine PUSH und POP 
Befehle. Man kann also keine Werte manuell auf den Stack legen. Er dient 
ausschließlich der Ablage der Sprungadressen. Bei den 18F hat man den 
Stack auf 32 Ebenen erhöht und den Befehlssatz u.a. um PUSH und POP 
erweitert. Auch hat man STATUS-Bits eingeführt, welche das Überlaufen 
des Stacks anzeigen. Initialisieren muss man bei den PICs den Stack aber 
nicht.

Gruß
Sven

Autor: Der Stack (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie praktisch

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht hier doch gar nicht um schneller oder billiger oder was ist 
besser. Was soll das nur immer dieses herumgehacke?

Das Thema dreht sich doch um den Stack und ging allmählich in die 
Richtung der Grundlagen des Stacks und wie dies auf verschiedenen µC 
geamacht wird. Ich wollte nur für den OP mal erklären, dass es auch noch 
andere Techniken gibt. Egal ob diese nun besser oder schlechter sind.

Da der OP aber scheinbar eh nicht mehr mit ließt, ist es auch egal. Ich 
denke die meisten hier wissen wie der Stack auf ihrer gewählten 
Plattform funktioniert. Und der Rest sollte es nach dem Lesen dieses 
Threads wissen.

Sven

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.