Frage zu RAMEND

Gast #2516407
Lesenswert?

Umgebung AVR-Studio 4.0, Atmega8

Habe ich folgendes richtig verstanden:

RAMEND ist eine 16bit-Variable und gibt mir das Ende des SRAM(speichers) 
an. Weil RAMEND 16bit groß ist und die Register in der Regel nur 8bit, 
muss ich RAMEND mit LOW oder HIGH auftrennen, um einmal "nur" die Bits 
0-7 (LOW) und zum anderen die Bits 8-15 (HIGH) zu bekommen?

Und der uC füllt von selber das SRAM von vorne, um z.B. Sprungadressen 
etc. zu speichern und damit ich nicht damit "kollidiere", fülle ich den 
Speicher bei selbstgemachten Anwendungen einfach von hinten?



SRAM

Begin

uC-Sprungadressen etc.
uC-Sprungadressen etc.
uC-Sprungadressen etc.
.
.
.
.
eigene Variable
eigene Variable
eigene Variable
eigene Variable
eigene Variable

Ende
Gast #2516415
Lesenswert?

Hi

>RAMEND ist eine 16bit-Variable und gibt mir das Ende des SRAM(speichers)
>an.

Bei kleineren AVRs gibt es das auch in 8 Bit.

>Und der uC füllt von selber das SRAM von vorne, um z.B. Sprungadressen
>etc. zu speichern und damit ich nicht damit "kollidiere", fülle ich den
>Speicher bei selbstgemachten Anwendungen einfach von hinten?

Genau umgekehrt. Der Stackpointer wird aud RAMEND gesetzt und bewegt 
sich in Richtung RAM-Anfang. Deine Variblen platzierst an den Anfang.

MfG Spess
#2516416
Lesenswert?

PC-Anfaenger schrieb:
> Umgebung AVR-Studio 4.0, Atmega8
>
> Habe ich folgendes richtig verstanden:
>
> RAMEND ist eine 16bit-Variable

Fast.
RAMEND ist einfach nur eine konstante Zahl, die dir im Assembler zur 
Verfügung steht.
(Um das Korinthenkacken zu verstehen: Eine Variable ist etwas, das man 
per Programm auch ändern kann)

> und gibt mir das Ende des SRAM(speichers)

genau

> an. Weil RAMEND 16bit groß ist und die Register in der Regel nur 8bit,
> muss ich RAMEND mit LOW oder HIGH auftrennen, um einmal "nur" die Bits
> 0-7 (LOW) und zum anderen die Bits 8-15 (HIGH) zu bekommen?

exakt

> Und der uC füllt von selber das SRAM von vorne, um z.B. Sprungadressen
> etc. zu speichern und damit ich nicht damit "kollidiere", fülle ich den
> Speicher bei selbstgemachten Anwendungen einfach von hinten?

Genau anders rum.
Der Stack beginnt am hinteren (oberen) Ende und wächst nach unten (hin 
zu kleineren Adressen)

Deswegen beginnen deine Speicherbelegungen im SRAM bei den kleinen 
Adressen. Aber das weiß der Assembler alles und vergibt die 
Reservierungen entsprechend.
Gast #2516537
Lesenswert?

Danke für die Antworten.

Mal ne Frage - SRAM und Stack - ist das identisch, ist mit SRAM zufällig 
S(tack)RAM gemeint? Weil in dem Tutorial ist mal von SRAM und mal von 
Stack die Rede, ich dachte, es wären zwei verschiedene Speicher-Arten, 
so wie das EEPROM auch etwas anderes wie das SRAM ist.
Gast #2516557
Lesenswert?

Hi

>Mal ne Frage - SRAM und Stack - ist das identisch, ist mit SRAM zufällig
>S(tack)RAM gemeint?

Nein. SRAM ist die Abkürzung für Static RAM. Der Stack ist ein 
Speicherbereich im RAM (welcher auch immer), der vom Controller 
verwaltet wird.

MfG Spess
Gast #2516585
Lesenswert?

Ich versuche grade das Kapitel SRAM aus dem AVR-Tutorial zu verstehen.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_SRAM

Ich habe das erste Beispielprogramm gestartet und will im Debugger 
sehen, was passiert. In einer Unterprogrammzeile timer0_overflow wird 
mit

lds temp1, PWMCount aus dem Speicher der Wert an der Speicherstelle 
PWMCount in temp1 geladen.

Meine Frage nun, wo kann ich im Debugger den Speicher sehen, da gibt es 
das Fenster "Memory" und ich kann in Unterklassen wählen zwischen

I/O
Data
EEPROM
Program
Register

I/O denke ich mal ist das gleiche wie das Fenster I/O-View, Register 
wird mir nur die Register anzeigen, EEPROM ist ein anderes Kapitel und 
hat nix mit SRAM zu tun. Also bleiben Data und Programm übrig, wobei ich 
mir aber nun nicht sicher bin, ob der Wert auch in Program stehen könnte 
- oder steht der gesichterte Wert an der Stelle PWMCount irgendwo in dem 
Fenster DATA?
Gast #2516597
Lesenswert?

Hi

>Also bleiben Data und Programm übrig, wobei ich
>mir aber nun nicht sicher bin, ob der Wert auch in Program stehen könnte
>- oder steht der gesichterte Wert an der Stelle PWMCount irgendwo in dem
>Fenster DATA?

Der RAM wird in Data dargestellt. Aber dort hast du keine Zuordnung zu 
deinen 'Variablen'.

Du kannst aber im Debug-Mode über View->Watch ein Fenster aktivieren in 
dem du deine 'Variablen' eintragen kannst. Da wird dir dann der Inhalt 
angezeigt.

MfG Spess
Gast #2516600
Lesenswert?

Hi
Der Grund für verschiedene Speicher (bereiche) ist die Physik. Ein SRAM 
ist nicht stabil und verändert sich bei Spannungsausfall. Bei Wiederkehr 
können zufällige Werte drin stehen. Dafür aber ist er unbegrenzt 
beschreibbar. Da ständig irgendwelche Adressen gemerkt oder Variablen 
verändert werden, darf der Speicher durch Schreibvorgänge nicht 
"zerstört" werden. Genau dies ist aer bei einem Flash-Ram der Fall. 
Scherlich, erst nach einigen tausend Schreibvorgängen, aber wenn man 
bedenkt, das ein µC mit 16 MHz getaktet ungefähr 1 Mio. Schreibvorgänge 
durchführen kann, wär der Flash sehr schnell hin....
Dem EEPRom ergeht es ebenso. Auch er "verbraucht" sich bei 
Schreibvogängen. Es sind zwar schon ein paar 10000, aber eben das selbe 
Problem. Durch die ständigen erforderlichen SChreibzugriffe auf den 
Speicher überlebt ein EEProm dies nicht allzulange und so hat schon 
manch einer seine Controller geschlachtet, weil er einfach den Hinweis 
im Datenblatt keine Beachtung geschenkt hat. Ich denke, nun ist es klar:
.DSEG für ständige Schreibzugriffe unbegrenzt, dafür aber flüchtig bei 
Spannungsausfall
.CSeg für Programm, da begrenzte Schreibzyklen
.ESeg für Programmparameter, die sich in begrenzter Häufigkeit ändern 
dürfen oder zur Datenrettung bei detektiertem Netzausfall und einer 
kleinen Gangreserve.
Gruß oldmax
Gast #2516620
Lesenswert?

Ich verstehe grade den Speicher nicht. Ich habe mir jetzt in dem Fenster 
Memory mal alle möglichen Teile angesehen.

Die Adresse ist immer 6stellig mit Hexadecimalzahlen

Register fängt z.B. an bei 00:00:00 und hört bei 00:00:1E auf. Da 1E_hex 
= 31_decimal ist, sind das die einzelnen Register.

Data fängt an bei

00:00:60 und geht bis 00:04:5E

Ich komme damit nicht klar, warum manche Speicherstellen immer wieder 
bei 00:00:00 anfangen, es müsste doch eigentlich einmal bei 00:00:00 
beginnen, zB. Programm oder so und geht bis zu seinem MaxWert und danach 
müsste dann z.B. Data kommen, Data fängt ja z.B. hier auch erst bei 
00:00:60 an und nicht bereits ab 00:00:00?

Und wenn ich drei HexPaare habe, dann habe ich ja 16^6-1 
Adressierungsmöglichkeiten bzw. 2^24-1 Speicherstellen, brauch ich denn 
überhaupt so viel Adressraum für 1kB Speicher?
Gast #2516633
Lesenswert?

spess53 schrieb:
> Variablen

schon klar, aber hinter einem Variablen-Namen müsste doch eine 
Speicherstelle "verborgen" sein, so könnte doch z.B. die Variable 
PWMcount in dem Fallbeispiel z.B. die Speicheradresse 00:00:FF haben??? 
Ich habe jetzt noch nicht kapiert, ob ich die Speicheradresse von 
"Variable" dierekt zuordne, oder vergibt der Compiler die 
Speicheradresse für Variable, ohne dass ich es weis? Wenn ja, hat der 
Compiler dann einen Schutz, dass er nicht zweimal die gleiche 
Speicherstelle einer Variablen zuordnet?
#2516652
Lesenswert?

PC-Anfaenger schrieb:

> Register fängt z.B. an bei 00:00:00 und hört bei 00:00:1E auf. Da 1E_hex
> = 31_decimal ist, sind das die einzelnen Register.
>
> Data fängt an bei
>
> 00:00:60 und geht bis 00:04:5E
>
> Ich komme damit nicht klar, warum manche Speicherstellen immer wieder
> bei 00:00:00 anfangen, es müsste doch eigentlich einmal bei 00:00:00
> beginnen, zB. Programm oder so und geht bis zu seinem MaxWert und danach
> müsste dann z.B. Data kommen, Data fängt ja z.B. hier auch erst bei
> 00:00:60 an und nicht bereits ab 00:00:00?

Programm und Data sind in verschiedenen Speicherbereichen untergebracht.

der Programmbereich hat seine eigene Zählung
Der Datenbereich hat seine eigene Zählung.

> Und wenn ich drei HexPaare habe, dann habe ich ja 16^6-1
> Adressierungsmöglichkeiten bzw. 2^24-1 Speicherstellen, brauch ich denn
> überhaupt so viel Adressraum für 1kB Speicher?

In deinem µC nicht.
Aber es gibt ja auch noch andere µC aus der gleichen Hersteller-familie, 
die dann entsprechend mehr Speicher haben. Und dann brauchst du die 
Adressiermöglichkeit.
Gast #2516660
Lesenswert?

Ich hab mal folgende Rechnung gemacht:

Data fängt erst bei 00:00:60 an, ich fragte mich, was kommt davor.

Addiere ich 3F (IO_View geht von 00:00:00 bis 00:00:3F) und 1F (Register 
geht von 00:00:00 bis 00:00:1F), dann komme ich auf 5E, dann vlt. noch 
ein Reserve-Bit, dann bin ich bei :60.

Könnte ich also sagen, dass IO_View und Register auch im SRAM sind, Data 
aber erst ab ..:60 beginnt, weil davor IO_View und Register kommen und 
Register und IO-View können sich auch so oft verändern, so dass die auch 
nicht in das EEPROM (ESEG) bzw. in das CSEG dürfen, wegen der begrenzten 
Schreibzyklen???
Gast #2516662
Lesenswert?

Karl Heinz Buchegger schrieb:
> Aber es gibt ja auch noch andere µC aus der gleichen Hersteller-familie,
> die dann entsprechend mehr Speicher haben. Und dann brauchst du die
> Adressiermöglichkeit.

Danke fuer den Hinweis, also ist das softwarebedingt so, dass das 
Fenster 6 Hexadecimalzahlen anzeigt, obwohl die für mein Modell Mega8 
das nicht gebraucht würde aber dann evtl. für eines dieser 
32bit-Modelle?
#2516665
Lesenswert?

PC-Anfaenger schrieb:

> Speicherstelle "verborgen" sein, so könnte doch z.B. die Variable
> PWMcount in dem Fallbeispiel z.B. die Speicheradresse 00:00:FF haben???

Ja, könnte sie.

> Ich habe jetzt noch nicht kapiert, ob ich die Speicheradresse von
> "Variable" dierekt zuordne, oder vergibt der Compiler die
> Speicheradresse für Variable,

das macht der Assembler/Compiler.

> Compiler dann einen Schutz, dass er nicht zweimal die gleiche
> Speicherstelle einer Variablen zuordnet?

Du musst zwischen 2 Dingen trennen.

Wenn du Assembler programmierst, dann fordert du mit

PWMCount .db

1 Byte an. Punkt. Damit ist für dich die Sache erledigt. Der Assembler 
liest dein Programm in einem Rutsch und teilt deinen 
Speicheranforderungen Speicheradressen zu.

Wenn wir von einem Compiler reden, dann reden wir von einer Hochsprache, 
wie zb C.
Der C Compiler übersetzt das Programm und filtert ebenfalls alle 
Speicheranforderungen (im globalen Speicher) raus. Er erzeugt ein sog. 
Object-File, welches im Grunde schon Machinencode, garniert mit 
Zusatzinfo (zb. welche Speicheranforderungen existieren).
Nach dem Compiler kommt der Linker zum Zug. Seine Aufgabe ist es, 
mehrere Object-Files zu einem Komplettprogramm zusammenzubauen. Dazu 
sieht er sich wieder die Speicheranforderungen in den einzelnen 
Object-Files an und weist ihnen Speicher zu.
Gast #2516672
Lesenswert?

Hi

>Register fängt z.B. an bei 00:00:00 und hört bei 00:00:1E auf. Da 1E_hex
>= 31_decimal ist, sind das die einzelnen Register.

$1F = 31

>Ich komme damit nicht klar, warum manche Speicherstellen immer wieder
>bei 00:00:00 anfangen, es müsste doch eigentlich einmal bei 00:00:00
>beginnen, zB. Programm oder so und geht bis zu seinem MaxWert und danach
>müsste dann z.B. Data kommen, Data fängt ja z.B. hier auch erst bei
>00:00:60 an und nicht bereits ab 00:00:00?

Das sind bei AVRs psysikalisch getrennte Speicher. Also können die auch 
alle mit Null anfangen. Aus diesem Grund gibt es auch verschiedene 
Befehle um auf RAM, Flash oder EEPROM zuzugreifen.

>Und wenn ich drei HexPaare habe, dann habe ich ja 16^6-1
>Adressierungsmöglichkeiten bzw. 2^24-1 Speicherstellen, brauch ich denn
>überhaupt so viel Adressraum für 1kB Speicher?

Bei mir (AVR-Studio 4.19) gibt es keine Doppelpunkte bei den Adressen. 
Ansonsten ist die sechsstellige Adresse nur eine Darstellungsfrage.

>Ich habe jetzt noch nicht kapiert, ob ich die Speicheradresse von
>"Variable" dierekt zuordne, oder vergibt der Compiler die
>Speicheradresse für Variable, ohne dass ich es weis?

Die Speicherstellen werden vom Assembler in der Reihenfolge vergeben in 
der du die sie definierst.

>Wenn ja, hat der
>Compiler dann einen Schutz, dass er nicht zweimal die gleiche
>Speicherstelle einer Variablen zuordnet?

Ja.

MfG Spess
#2516673
Lesenswert?

PC-Anfaenger schrieb:

> Könnte ich also sagen, dass IO_View und Register auch im SRAM sind, Data
> aber erst ab ..:60 beginnt, weil davor IO_View und Register kommen und
> Register und IO-View können sich auch so oft verändern, so dass die auch
> nicht in das EEPROM (ESEG) bzw. in das CSEG dürfen, wegen der begrenzten
> Schreibzyklen???

Der eigentliche Grund ist ein anderer, aber ja: so kann man das sagen. 
Man kann jedes Register wie eine SRAM Zelle ansehen und mit genau den 
gleichen Methoden darauf zugreifen.

Für dein Programm sieht es so aus, als ob im Speicher ganz vorne bei den 
kleinen Adressen erst mal alle Register im Speicher liegen. Und erst 
danach kommt der Speicherteil, in dem du gefahrlos Werte ablegen kannst. 
Physikalisch ist das im µC zwar anders realisiert, aber das bedeutet ja 
nicht, dass sich das für dein Programm auch anders darstellen muss.
Gast #2516722
Lesenswert?

Vielen Dank fuer Eure vielen Erklärungen, jetzt hab ich schon eine ganze 
Menge gelernt heute.

spess53 schrieb:
> Die Speicherstellen werden vom Assembler in der Reihenfolge vergeben in
> der du die sie definierst.

gut,

also wird in dem Beispiel in dem Tutorial zu erst im .dseg

PWMCount .BYTE  1 definiert mit einem Bype länge,
dann OCR_1
dann OCR_2

... auch jeweils mit einem Byte länge, und da der Speicher Data bei :60 
anfängt, hat also PWMCount die Speicheradresse $0060, OCR_1 $0061, OCR_2 
$0062

und wenn dort stünde:

PWM_Count .BYTE 5,

dann hätte PWM_Count immer noch die Adresse $0060, aber OCR_1 dann die 
Adresse $0065(also fünf bit weiter)??

spess53 schrieb:
> Bei mir (AVR-Studio 4.19) gibt es keine Doppelpunkte bei den Adressen.
> Ansonsten ist die sechsstellige Adresse nur eine Darstellungsfrage.

bei mir auch, aber mit den Doppelpunkten fand ich es schreibtechnisch 
etwas übersichtlicher.
Gast #2516728
Lesenswert?

Mal noch ne Frage, angenommen, ich würde mir ne Variable mit 3Byte 
definieren:


.dseg

Vaiable1 .BYTE 3

dass müsste doch zu Fehlern führen, oder?

Und wenn ich schreiben würde

Variable1 .BYTE 2

und würde die dann verwenden wollen, z.B. in das 16bit-Paar XL/XH bzw. 
r26,r27 zuordnen wollen, dann müsste ich wieder schreiben:

ldi XH, HIGH(Variable1)
ldi XL, LOW(Variable1)

??
#2516746
Lesenswert?

PC-Anfaenger schrieb:

> also wird in dem Beispiel in dem Tutorial zu erst im .dseg
>
> PWMCount .BYTE  1 definiert mit einem Bype länge,
> dann OCR_1
> dann OCR_2
>
> ... auch jeweils mit einem Byte länge, und da der Speicher Data bei :60
> anfängt, hat also PWMCount die Speicheradresse $0060, OCR_1 $0061, OCR_2
> $0062

Fast.
Speicher Allokierungen sind beim AVR aus technischen Gründen immer auf 
einer gerade Adresse. Also rundet der Assembler selbstständig auf.

Aber abgesehen davon stimmt es.

> bei mir auch, aber mit den Doppelpunkten fand ich es schreibtechnisch
> etwas übersichtlicher.

Das ist keine so gute Idee.
Wir können nicht in deinen Kopf schauen und auch nicht dir über die 
Schulter schauen. Schreib die Dinge so, wie du sie am Bildschirm liest. 
Dann kann ich bei mir auf dne Bildschirm schauen, suchen wo bei mir die 
exakt gleiche Angabe am Bildschirm steht und weiß (hoffentlich) wo du 
hingeschaut hast beim Ablesen.
#2516756
Lesenswert?

PC-Anfaenger schrieb:

> .dseg
>
> Vaiable1 .BYTE 3
>
> dass müsste doch zu Fehlern führen, oder?

Warum sollte es?

> Und wenn ich schreiben würde
>
> Variable1 .BYTE 2
>
> und würde die dann verwenden wollen, z.B. in das 16bit-Paar XL/XH bzw.
> r26,r27 zuordnen wollen, dann müsste ich wieder schreiben:
>
> ldi XH, HIGH(Variable1)
> ldi XL, LOW(Variable1)

Das macht etwas anderes. Das lädt die Adresse, also wo Variable1 
gespeichert ist. Wenn du den Inhalt der Variable1 willst, musst du 
andere Befehle verwenden.

Beides kann sinnvoll sein. Es kann sinnvoll sein, die Adresse einer 
Variablen zu laden, es kann aber auch sinnvoll sein, ihren Inhalt zu 
laden.


Du musst unterscheiden zwischen der Nummer, die aussen auf einem 
Briefkasten draufsteht (zb in einer Wohnsiedlung) und der Zahl, die auf 
ein Zettel steht, die im Briefkasten drinn liegt. Beides ist nicht 
dasselbe.
Das eine ist seine Adresse (die steht draussen drauf, damit der 
Briefträger weiß in welchen er einwerfen muss), das andere ist der 
Inhalt (zb die Steuernachzahlung in Euro).

Es kann jetzt sinnvoll sein, mit den Adressnummern der Briefkästen zu 
rechnen. Es kann aber auch sinnvoll sein, mit dem Inhalt eines 
bestimmten Briefkastens zu rechnen. Es kann auch sinnvoll sein, zuerst 
mit der Adressnummer der Briefkästen zu rechnen und dann mit der Zahl 
die man daraus erhält sich den Inhalt dieses errechneten Briefkastens 
anzusehen.
Gast #2516804
Lesenswert?

Hi

>Fast.
>Speicher Allokierungen sind beim AVR aus technischen Gründen immer auf
>einer gerade Adresse. Also rundet der Assembler selbstständig auf.

Beim Flash, ja. Im Ram wird (vom Assembler) nichts auf geradzahlige 
Adressen gebracht.


>.dseg
>Vaiable1 .BYTE 3
>dass müsste doch zu Fehlern führen, oder?
>Und wenn ich schreiben würde
>Variable1 .BYTE 2
>und würde die dann verwenden wollen, z.B. in das 16bit-Paar XL/XH bzw.
>r26,r27 zuordnen wollen, dann müsste ich wieder schreiben:
>ldi XH, HIGH(Variable1)
>ldi XL, LOW(Variable1)

Dann hast du die Adresse in X. Du willst aber den Inhalt haben:
1
  lds XL,Variable1
2
  lds XH,Variable1+1
Gast #2517020
Lesenswert?

Karl Heinz Buchegger schrieb:
> Es kann jetzt sinnvoll sein, mit den Adressnummern der Briefkästen zu
> rechnen. Es kann aber auch sinnvoll sein, mit dem Inhalt eines
> bestimmten Briefkastens zu rechnen. Es kann auch sinnvoll sein, zuerst
> mit der Adressnummer der Briefkästen zu rechnen und dann mit der Zahl
> die man daraus erhält sich den Inhalt dieses errechneten Briefkastens
> anzusehen.

Also wie diese Pointer bei C? Weil das ist ja dann das gleiche, wenn ich 
den Inhalt einer Variablen haben wollte, dann musste ich glaub ich immer 
ein kaufmännisches & davorsetzen.
Gast #2517047
Lesenswert?

spess53 schrieb:
> Dann hast du die Adresse in X. Du willst aber den Inhalt haben:
>   lds XL,Variable1
>   lds XH,Variable1+1

Das low/high würde hier nicht funktionieren?

lds XL, LOW(Variable) wenn ich Variable zuvor mit dseg als 
2Byte-Variable gekennzeichnet habe? Oder ist die Variable auch nur 1Bit 
groß, ich habe aber dem Compiler durch .Byte 3 gesagt, dass er dahinter 
noch zwei zusätliche Bytes freihalten soll?

Karl Heinz Buchegger schrieb:
> PC-Anfaenger schrieb:
>
>> .dseg
>>
>> Vaiable1 .BYTE 3
>>
>> dass müsste doch zu Fehlern führen, oder?
>
> Warum sollte es?

Darum hab ich auch gefragt, ob Variable1, wenn sie als 3Byte-Variable 
deklariert ist, nicht mit einem 16Bit-Befehl funktioniert, weil ich doch 
mit dem Befehl adiw ja auch eine 16-Bit-Zahl verändere, dann dürfte das 
ja bei einer 3Byte-Zahl ja nicht klappen und es müsste ein Fehler 
kommen. Wenn ich aber nun einfach sage, die Variable1 ist auch wenn 
.BYTE 3dahinter steht, vom Wert her auch nur 1 Byte groß, es werden aber 
zwei Byte dahinter Platz gelassen und ich muss dann dahinter so drauf 
zugreifen:

spess53 schrieb:
> Dann hast du die Adresse in X. Du willst aber den Inhalt haben:
>   lds XL,Variable1
>   lds XH,Variable1+1

Und so müsste ich ja dann ohne Probleme auch eine 24-Bit-Zahl verwenden 
können, wenn ich einfach schreibe

.dseg
Variable_24bit .BYTE 3

Und dann könnte ich mir theoretisch selber drei Variablen benennen

z.B.
WL = r20 WL = W_low
WM = r21 WM = W_middle
WH = r22 WH = W_high

Und dann könnte ich mir die Variable dann so zum Bearbeiten laden:

lds WL, Variable_24bit
lds WM, Variable_24bit+1
lds WH, Variable_24bit+2

Karl Heinz Buchegger schrieb:
> Fast.
> Speicher Allokierungen sind beim AVR aus technischen Gründen immer auf
> einer gerade Adresse. Also rundet der Assembler selbstständig auf.

Dazu hab ich mir überlegt - dass würde ja bedeuten, angenommen, mein 
Adressraum ginge von 0 bis F, dann hab ich 16 Adressen. Soll eine 
Varible immer 16Bit haben, dann kann ich max. 8 Varialben benennen. Will 
ich aber nur 8bit-Variablen haben, dann kann ich auch maximal 8 
Variablen benennen, weil der uC nun immer auf gerade Adresse aufrundet? 
Naja, es wird schon seinen Grund haben, warum das so ist.
#2517105
Lesenswert?

PC-Anfaenger schrieb:
> spess53 schrieb:
>> Dann hast du die Adresse in X. Du willst aber den Inhalt haben:
>>   lds XL,Variable1
>>   lds XH,Variable1+1
>
> Das low/high würde hier nicht funktionieren?

Du musst dir klar machen, was der Befehl LDS überhaupt tut.
Im Beispiel von oben: LDS ist die Anweisung:

Geh zum Briefkasten 'Variable1' (das ist irgendeine Zahl) und schreib 
den Inhalt des Zettels ab und übertrage ihn in dein Notizbuch unter 'XH' 
(was gleichbedeutend mit R27 ist)

Sowohl auf dem Zettel, als auch unter XL, können Werte von 0 bis 255 
(nämlich genau das, was mit einem Byte möglich ist) abgelegt werden.

Kein Mensch braucht da ein Low oder ein High

LDI  R17, Low( Variable )

macht aber ganz was anderes.
Das sagt, wieder am Beispiel:

Nimm die Nummer vom Briefkasten und schreibe diese Nummer in dein 
Notizbuch unter dem Stichwort R17.
Jetzt kannst du aber tausend Briefkästen haben. Die Nummer des 
Briefkastens passt nicht mehr in 1 Byte. Wenn du also die NUmmer des 
Kastens in R17 laden willst, dann hast du ein Problem: sie passt nicht 
hinein. Also musst du dich entscheiden welchen Teil der Nummer du haben 
willst.

> lds XL, LOW(Variable) wenn ich Variable zuvor mit dseg als
> 2Byte-Variable gekennzeichnet habe?
...
> Darum hab ich auch gefragt, ob Variable1, wenn sie als 3Byte-Variable
> deklariert ist,

Ich glaube, du machst dir da vom Begriff 'Variable' eine etwas falsche 
Vorstellung ....

> nicht mit einem 16Bit-Befehl funktioniert, weil ich doch
> mit dem Befehl adiw ja auch eine 16-Bit-Zahl verändere, dann dürfte das
> ja bei einer 3Byte-Zahl ja nicht klappen und es müsste ein Fehler
> kommen.

... denn für den Assembler gibt es keine Variablen. Für den existeren 
nur Speicherzellen, die eine Adresse haben und in jeder Speicherzelle 
wird ein Byte gespeichert welches gelesen und geschrieben werden kann.

Was du mit diesem Speicher machst, mit welchen Befehlen du welches Byte 
angreifst, das ist ganz alleine dein Bier. Das interessiert weder den 
Assembler noch den µC. Die führen nur uneingeschränkt deine Befehle aus. 
Wenn du dir 50 Bytes in Folge reservierst, aber immer nur das 5.te davon 
benutzt um dort Werte zu speichern oder zu lesen, dann ist denen das 
auch recht. Da kommt die Anweisung: Schreibe den Inhalt von R18 in die 
Speicherzelle mit der Adresse 52 und genau das macht der µC dann auch. 
Ob das das erste Byte oder das zweite oder das 5.te Byte von

Variable .BYTE 10

ist, interessiert ausser dem Programmierer keinen und kein Mechanismus 
schützt dich davor, da einen Fehler zu machen.

'Variablen' gibt es nur in Hochsprachen. Wir verwenden den Begriff 
manchmal im Assembler um anzudeuten, dass es sich um Speicher handelt, 
der vom Programm verändert werden kann, aber all das was in einer 
Hochsprache dann noch am Begriff 'Variable' hängt, existiert im 
Assembler schlicht und ergreifend nicht, bzw. liegt in der Hand des 
Programmierers.
#2517106
Lesenswert?

PC-Anfaenger schrieb:

> Karl Heinz Buchegger schrieb:
>> Fast.
>> Speicher Allokierungen sind beim AVR aus technischen Gründen immer auf
>> einer gerade Adresse. Also rundet der Assembler selbstständig auf.
>
> Dazu hab ich mir überlegt - dass würde ja bedeuten, angenommen, mein
> Adressraum ginge von 0 bis F, dann hab ich 16 Adressen. Soll eine
> Varible immer 16Bit haben, dann kann ich max. 8 Varialben benennen. Will
> ich aber nur 8bit-Variablen haben, dann kann ich auch maximal 8
> Variablen benennen, weil der uC nun immer auf gerade Adresse aufrundet?
> Naja, es wird schon seinen Grund haben, warum das so ist.

Vergiss das. Das war ein Fehler von mir.
Du findet nichts statt.
Gast #2517161
Lesenswert?

Hi

>Das low/high würde hier nicht funktionieren?

Nein. Variable1 bezeichnet eine Adresse, auf der sich ein Byte befindet, 
nicht was dort abgelegt ist. Wenn beispielsweise Variable auf die 
Adresse $0123 zeigt ergäbe der Ausdruck LOW(Variable) den Wert $23 und 
High(Variable) den Wert $01. Und das wären dann die Adressen von denen 
du mit lds liest:

    lds XL, $0023
    lds XH, $0001

>Darum hab ich auch gefragt, ob Variable1, wenn sie als 3Byte-Variable
deklariert ist, nicht mit einem 16Bit-Befehl funktioniert,....

16-Bit-Befehle können bei AVRs nur auf Register zugreifen, nicht auf den 
Speicher. Wenn du also z.B. zu einem 24-Bit Wert etwas addieren willst 
muss er erst aus dem Speicher gelesen werden.

>Und so müsste ich ja dann ohne Probleme auch eine 24-Bit-Zahl verwenden
>können, wenn ich einfach schreibe....

Bevor du anfängst mit 16-, 24-, ..Bit Werten zu hantieren solltest du 
dich erst mal mit dem Handwerkszeug, sprich Befehlssatz, 
Adressierungsarten, Wirkung der Befehle auf die Flags, 
Assembler-Direktiven, Assembler-Expressions, Assembler-Funktionen usw. 
vertraut machen.

>Karl Heinz Buchegger schrieb:
>> Fast.
>> Speicher Allokierungen sind beim AVR aus technischen Gründen immer auf
>> einer gerade Adresse. Also rundet der Assembler selbstständig auf.

Im RAM nicht. Siehe:
Beitrag "Re: Frage zu RAMEND"

Und der Flash ist Word-Organisiert (16 Bit). Dort abgelegte Bytes 
beginnen an (durch die Byte-Brille gesehen) an einer geraden Adresse. 
Liegen aber dann ohne Abstand hintereinander (2 Byte pro Word).

MfG Spess
Gast #2518239
Lesenswert?

Ich hab nochmal kurz eine generelle Frage zu in den Speichern abgelegten 
Variablen.

Wenn ich eine Veränderung vornehmen möchte, z.B. eine Zahl zu einer im 
SRAM gespeicherten "Variable" (ich schreib das jetzt einfach, auch wenn 
ich nun gelernt hab, dass Variable nicht der richtige Begriff ist) 
dazuaddieren möchte - dann geht dies nicht dierekt, sondern ich muss 
erst den Inhalt der Speicherstelle in einen Register holen, die 
Veränderung im Register machen und dann den Wert vom Register an die 
Speicherstelle kopieren -hab ich das so richtig verstanden? Und wenn das 
beim SRAM so ist, dann müsste das später beim EEPROM auch so sein - nur 
halt mit anderen Befehlen, die EEPROM-spezifisch sind und nicht 
SRAM-spezifisch?
Gast #2518297
Lesenswert?

In diesem Beitrag von etwas weiter oben hast Du mir den Link gegeben:

spess53 schrieb:
> Im RAM nicht. Siehe:
> Beitrag "Re: Frage zu RAMEND"

Dieser Link zeigt nicht nur auf die Seite, sondern auch noch auf die 
Zeile, so dass man nicht danach suchen muss. Mich würde mal 
interessieren, wie Du das gemacht hast. Das könnte auch praktisch sein, 
wenn man z.B. aus dem AVR-Tutorial aus einem Kapitel auf eine einzelne 
Stelle am Ende verweisen möchte. Wenn ich so einfach nur den Link 
kopiere, der oben in der Adress-Zeile des Browsers steht, komme ich 
immer nur auf den Seitenanfang und der Leser müsste dann z.B. weit 
scrollen, bis der zu der gewünschten Stelle kommt.
Gast #2518324
Lesenswert?

Hi

Einfach mit dem Cursor auf den Titel in der orangenen Titelzeile des 
Beitrags gehen, Rechtsclick und im Menu 'Linkadresse kopieren' 
auswählen. Dann mit Einfügen in deien Beitrag kopieren.

MfG Spess

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren