Hallo,
ist zwar eine Anfängerfrage aber ich komme trotzdem nicht drauf, beim
debuggen ist mir aufgefallen, dass wenn ich mir den Speicher (Programm)
anschaue, vier Bytes in einer Zeile sind aber die Adresse nur 2 Byte
breit ist.
Kann mir das mal jemand kurz erklären?
Gruß, Jürgen
kann es sein, dass im ersten Byte der Befehl steht (sofern 1 Byte
Befehl) und im 2 Byte steht der Wert?
Wie funktioniert das dann aber mit dem Auslesen einer Zeichenkette?
Es müssten dann ja immer 2 Zeichen mit einmal ausgelesen werden?
Hallo,
in Assembler gibt es dazu LPM (Load from Program Memory).
Dieser lädt aus einer Adresse, auf die Z, Y, X zeigt, ein Byte in ein
Register. Dieser Zugriff adressiert Byte-Weise, deshalb muß die
Word-Adresse dort mit 2 multipliziert werden.
Programmbeispiele suchen gehen, sieht dann z.B. so aus:
.CSEG
...
ldi ZL, low(2*textmarke)
ldi ZH, high(2*textmarke)
loop:
lpm r16,Z+
tst r16 ; auf 0-Byte testen
breq loop_end
... ; was mit dem Byte machen
rjmp loop ; und weiter
...
textmarke:
.db "Das ist ein Text",0
Der Inhalt, der ab .db im Flash liegt wird Wordweise gespeichert.
Wenn es eine ungrade Byte-Anzahl in der Zeile ist, hängt der Assembler
ein zusätzliches 0-Byte an und gibt eine Warnung (mehr ein Hinweis auf
das Padding-Byte) aus.
Darauf muß man unbedingt achten, wenn man z.B. Tabellen im Flash baut
und den Tabellenzugriff zur Laufzeit im Programm berechnet.
Gruß aus Berlin
Michael
aha, wenn der Befehl also Byteweise arbeitet, dann ließt er beim ersten
Durchlauf das erste Byte und beim zweiten Durchlauf das zweite Byte.
Wenn dann der dritte Durchlauf kommt, wird der Z-Pointer um eins erhöht
und wieder das erste Byte der nächsten Adresse gelesen.
Hab ich das jetzt richtig verstanden?
Zur Zeit programmiere ich nämlich noch in Assembler und versuche die
Arbeitsweise des MCs zu verstehen, macht sich einfacher beim Debugging
wenn man Bescheid weiß wie das Teil arbeitet.. :-)
Jürgen wrote:
> aha, wenn der Befehl also Byteweise arbeitet, dann ließt er beim ersten> Durchlauf das erste Byte und beim zweiten Durchlauf das zweite Byte.
Nein, nicht wirklich...
> Wenn dann der dritte Durchlauf kommt, wird der Z-Pointer um eins erhöht
Nein...
> und wieder das erste Byte der nächsten Adresse gelesen.
Nicht ganz...
LPM interpretiert den Z-Pointer anders als andere Befehle. Schau mal in
die Befehlsbeschreibung zu LPM (AVR-Studio-Online-Hilfe, also Cursor im
Editor auf LPM stellen und F1 drücken). Das Bit 0 des Z-Pointers
entscheidet bei LPM, ob das H-Byte oder das L-Byte gelesen wird, Bit 1
bis 15 geben die Word-Adresse der Flash-Zelle an. Das sieht dann unterm
Strich so aus, als adressiere der Z-Pointer byteweise. Der Z-Pointer
wird deshalb auch nicht mit der Wordadresse der Flash-Zelle (durch das
Label an den Daten repräsentiert) geladen, sondern mit dem Doppelten
davon (Label * 2). Das ist aber nur bei LPM (und SPM, aber das ist eine
andere Lektion) der Fall. Für andere indizierte Flash-Zugriffe über
Z-Pointer (IJMP, ICALL) muss der Z-Pointer mit dem korrekten Wert
(Label) geladen werden.
>> Hab ich das jetzt richtig verstanden?
Bisher nicht ganz, jetzt vermutlich schon.
> Zur Zeit programmiere ich nämlich noch in Assembler und versuche die> Arbeitsweise des MCs zu verstehen, macht sich einfacher beim Debugging> wenn man Bescheid weiß wie das Teil arbeitet.. :-)
Das ist eine gute Einstellung zur Materie. Verstehen kannst Du die
Arbeitsweise der ASM-Befehle aber erst, wenn Du die Architektur der AVRs
und die daraus resultierenden Adressierungsarten verstanden hast. Dabei
hat es uns ATMEL schon leicht gemacht, indem die Mnemonics für
verschiedene Adressierungsformen unterschiedlich sind. Es gibt also kein
Einheits-MOV für alle Lade- und Kopier-Befehle wie beim 8085/8086.
Frohen Rest vom Pfingstfest...
...
so ganz verstanden hab ich es leider immer noch nicht.
Hinter jeder Speicheradresse stecken ja 2 Zeichen, weil eine
Speicherzelle 16 Bit breit ist. Nun wird aber der Z-Pointer nach jedem
Durchlauf um eins erhöht. Das bedeutet aber, dass mit jedem Durchlauf 2
Zeichen eingelesen werden müssten, was aber auch nicht geht.
Hi
>Hinter jeder Speicheradresse stecken ja 2 Zeichen, weil eine...
Nein. Der Z-Pointer zeigt genau auf ein Byte (Zeichen). Für das nächste
Byte muss er incrementiert werden.
Mach es doch so, wie Michael schon weiter oben beschrieben hat.
Übrigens hat der 'lpm'-Befehl verschiedene Varianten.
MfG Spess
Schau mal auf Seite 7 der Datei im Anhang.
Bit 0 im Z-Pointer adressiert das Byte innerhalb der zwei Bytes großen
Flash-Zelle, Bit 1 bis 15 adressieren eine von 32K Flash-Zellen. Das
wirkt dann so, als würde man den Flash byteweise adressieren. Daher muss
man darauf achten, dass man den Z-Pointer für LPM nicht mit der
tatsächlichen Adresse (Word-basiert) lädt, sondern mit dem Doppelten
davon.
...
Jetzt hab ichs, klar der Wert im Z-Pointer ist ja doppelt so groß.
Deswegen wird, wenn man das zurückrechnet, theoretisch nur bei jeden
zweiten Durchlauf der Adresspointer erhöht.
Danke nochmal, mir ist da jetzt einiges klarer geworden.