Forum: Mikrocontroller und Digitale Elektronik Warum macht man das?


von Axel Hermann (Gast)


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

von dieter (Gast)


Lesenswert?

google mal nach stackpointer

von meiner (Gast)


Lesenswert?

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

von Unbekannter (Gast)


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.

von Christoph db1uq K. (christoph_kessler)


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.

von Gast (Gast)


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").

von Der Stack (Gast)


Lesenswert?


von max (Gast)


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

von Paul Baumann (Gast)


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

von max (Gast)


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 ^^

von Jadeclaw D. (jadeclaw)


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.

von Sven S. (stepp64) Benutzerseite


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

von Der Stack (Gast)


Lesenswert?

Wie praktisch

von Sven S. (stepp64) Benutzerseite


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

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.