Forum: Mikrocontroller und Digitale Elektronik Pointer zeigt auf falschen Speicherbereich ASM AVR


von pacer (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe folgendes Problem:
mit den Befehlen
ldi XL,low(Zeilenanfang*2)
ldi XH,high(Zeilenanfang*2)
setze ich theoretisch den Pointer auf die entsprechende Speicherzelle im 
Programmspeicher. Wenn ich mir aber den Inhalt der Register XH/XL 
anschaue stimmt das so nicht.
kann mir jemand sagen was ich falsch mache?

Grüße, Jürgen

von Peter (Gast)


Lesenswert?

> kann mir jemand sagen was ich falsch mache?
ja, du verwendest das falsche bildformat. JPG nimmt man für Fotos und 
nicht für Bildschirmfotos.

lass mal das *2 weg, dann stimmt es doch.

von spess53 (Gast)


Lesenswert?

Hi

Wieso stimmt doch. Unten wird die Wortadresse angezeigt. X enthält die 
Byteadresse: $A19*2 = $1432

MfG Spess

von pacer (Gast)


Lesenswert?

stimmt, ich habe angenommen, dass der Programmspeicher wortorieniert ist 
und damit immer das *2 vorhanden sein muss. Offensichtlich habe ich es 
noch nicht verstanden wie es richtig funktioniert.
Komisch ist aber, dass es bei mir bisher mit *2 funktioniert hat.
Selbst im AVR-Tutorial: Speicher steht es so drin.

Vielleicht kann mich ja mal jemand kurz aufklären.

von Peter (Gast)


Lesenswert?

es ja die Frage welchen Wert du in X haben willst, die Word-Adresse oder 
die Byte-Adresse.

von pacer (Gast)


Lesenswert?

in der Tabelle stehen Startadressen für verschiedene Strings welche ich 
ausgeben möchte. Ich will also mit dem Wert aus der Speicherzelle in 
einen 2. Pointer laden.
Ich kann deine Frage leider nicht beantworten, weil ich nicht weiß worin 
der Unterschied besteht. Die Frgae muss ich also zurückgeben.
Wann nimmt man die Byteadresse und wann die Wortadresse?

von Diensthabender Troll (Gast)


Lesenswert?

Programmspeicher ist nicht über X-Pointer erreichbar, da musst Du schon 
den Z-Pointer nehmen...

von Karl H. (kbuchegg)


Lesenswert?

pacer schrieb:

> Wann nimmt man die Byteadresse und wann die Wortadresse?


Es hängt davon ab, welchen Befehl du dann in weiterer Folge benutzt. 
Adressen im Flash werden vom Assembler immer als die Wortadresse 
berechnet. Das ist für Befehle wie rcall oder rjmp genau richtig. lpm 
will aber eine Byteadresse haben, und daher muss man mit 2 
multiplizieren.

von pacer (Gast)


Lesenswert?

folgendes will ich programmieren:
ich habe einen Datenbreich mit mehreren aufeianderfolgenden Strings.
weiterhin habe ich eine zweite Tabelle in der die Low-Byte-Adresse vom 
Beginn eines jeeden Strings stehen Auf diese Tabelle zeigt ein Pointer, 
den ich beliebig incrementieren oder decrementieren kann. Decremtentiere 
ich zum Beispiel, soll die Adresse ausgelesen werden und an den zweiten 
Pointer übergeben werden. dieser leißt dann den Inhalt des Strings aus. 
Mit diesem Konstrukt kann ich schnell einen String über oder unter dem 
aktuellen String ausgeben, ohe irgenwie den Anfang oder das Ende des 
Strings detektieren zu müssen.
Da ich das so noch nie gemacht habe muss ich mich da langsam rantasten 
und kann nicht sofort segen wie der nächste Befehl aussieht. Kann man zB 
nicht mit dem X-Pointer den Programmspeicher auslesen wäre der nächste 
Befehl ein LPM Befehl mit einem Anschließenden mov zum Laden des 2. 
Pointers.

ich hoffe ich habe mich nicht zu kompliziert ausgedrückt

von Gast (Gast)


Lesenswert?

Zunächst einmal - LPM geht nur mit dem Z-pointer, wie
bereits ausgeführt wurde. Ein Lösungsansatz wäre z.B.
erst einmal die Flash-Adresse in den Z-pointer zu laden,
mit zweimaligem LPM den Inhalt auszulesen und in den
Stack zu schieben. Danach aus dem Stack in den Z-pointer
zurück holen.

Ich habe schon mehrfach erlebt, dass der AVR-Assembler
mit der Berechnung von Adressen so seine Probleme hat,
sobald es um einen Mix von Strings und Byte-Werten geht.
Völlig unabhängig davon, ob man auf das korrekte word-
alignment geachtet hat. Es kann schon mal zu seltsamen
Effekten kommen.

Mein Vorschlag - so habe ich das Problem dann meistens
in den Griff bekommen:

vor dem Label "Zeilenanfang" ein
.db 0, 0
oder
.dw 0
einschieben.
Oder - worst case - ein
.org 0x0A1B

von Hannes L. (hannes)


Angehängte Dateien:

Lesenswert?

Schau mal hier (Anhang), ist zwar nicht ganz so, wie Du es Dir 
vorstellst, klappt aber ganz gut zur Ausgabe indizierter Texte.

Und hier ein Anwendungsbeispiel, die Routine schreibt menüpunktabhängige 
Texte in die erste und letzte Zeile des LCDs 24x8, wobei "mp" das 
Register ist, das den Menüpunkt (der auch als Index auf die Textarrays 
dient) enthält:
1
 locate 0,0                 ;Position der LCD-Ausgabe
2
 printt mt_head,mp          ;Kopfzeile Menuepunkt ausgeben
3
 locate 7,0                 ;Position der LCD-Ausgabe
4
 printt mt_key,mp           ;Fusszeile Tastenzuordnung ausgeben

Und hier die zugehörigen Daten im Flash:
1
mt_head:        ;obere Menuezeilen (Menuepunkte)
2
.dw mt_000,mt_010,mt_020,mt_030,mt_040,mt_050,mt_060,mt_070
3
.dw mt_080,mt_090,mt_100,mt_110,mt_120,mt_130,mt_030,mt_030
4
.dw mt_160
5
6
mt_000:     .db " ***   Edit-Mode    *** ",1,0
7
mt_010:     .db "Datentransfer mit PC    ",1,0
8
mt_020:     .db "zur ersten/letzten Zeile",1,0
9
mt_030:     .db "eine Zeile hoch/runter  ",1,0
10
mt_040:     .db "Zeile de/aktivieren     ",1,0
11
mt_050:     .db "Einstellung Minute x 10 ",0,0
12
mt_060:     .db "Einstellung Minute x 1  ",0,0
13
mt_070:     .db "Einstellung Sekunde x 10",0,0
14
mt_080:     .db "Einstellung Sekunde x 1 ",0,0
15
mt_090:     .db "Einstellung Zehntelsek. ",0,0
16
mt_100:     .db "Auswahl Zuendgeraet     ",0,0
17
mt_110:     .db "Zuendkreisnummer x 10   ",0,0
18
mt_120:     .db "Zuendkreisnummer x 1    ",0,0
19
mt_130:     .db "Daten Uebernehmen       ",1,0
20
21
mt_160:     .db " *** Feuerwerk-Mode *** ",1,0
22
23
mt_key:         ;untere Menuezeilen (Tastenzuordnung)
24
.dw mt_007,mt_017,mt_027,mt_037,mt_047,mt_057,mt_067,mt_077
25
.dw mt_087,mt_097,mt_107,mt_117,mt_127,mt_137,mt_037,leerz
26
.dw mt_167,mt_177,mt_187,mt_197,mt_197,mt_177a,mt_177a,mt_177a
27
.dw mt_167,mt_197,mt_197
28
29
mt_007:     .db "       Run         ++++>",0,0
30
mt_017:     .db "<----  Load  Save  ++++>",0,0
31
mt_027:     .db "<----  Home  End   ++++>",0,0
32
mt_037:     .db "<----  Up    Down  ++++>",0,0
33
mt_047:     .db "<----  deakt aktiv ++++>",0,0
34
mt_057:     .db "<----  +10m  -10m  ++++>",0,0
35
mt_067:     .db "<----  +1 m  -1 m  ++++>",0,0
36
mt_077:     .db "<----  +10s  -10s  ++++>",0,0
37
mt_087:     .db "<----  +1 s  -1 s  ++++>",0,0
38
mt_097:     .db "<---- +0,1s -0,1s  ++++>",0,0
39
mt_107:     .db "<----  +1    -1    ++++>",0,0
40
mt_117:     .db "<----  +10   -10   ++++>",0,0
41
mt_127:     .db "<----  +1    -1    ++++>",0,0
42
mt_137:     .db "<----  Save  Abort      ",0,0
43
44
mt_167:     .db "             Edit  ++++>",0,0
45
mt_177:     .db "<Menu  Start Skip  Set >",0,0
46
mt_177a:    .db "       Stop  Skip       ",0,0
47
mt_187:     .db "<----  Up    Down  ++++>",0,0
48
mt_197:     .db "<Stop  Shot  Skip  Up   ",0,0

...

von Gast (Gast)


Lesenswert?

oder - etwas unschön, aber wenn es hilft -
ein

nop

einschieben.

von Hannes L. (hannes)


Lesenswert?

Gast schrieb u.a.:

> Ich habe schon mehrfach erlebt, dass der AVR-Assembler
> mit der Berechnung von Adressen so seine Probleme hat,
> sobald es um einen Mix von Strings und Byte-Werten geht.
> Völlig unabhängig davon, ob man auf das korrekte word-
> alignment geachtet hat. Es kann schon mal zu seltsamen
> Effekten kommen.

Das kann ich nicht bestätigen.

>
> Mein Vorschlag - so habe ich das Problem dann meistens
> in den Griff bekommen:
>
> vor dem Label "Zeilenanfang" ein
> .db 0, 0
> oder
> .dw 0
> einschieben.
> Oder - worst case - ein
> .org 0x0A1B

Das ist definitiv nicht nötig, auch das NOP nicht.

...

von pacer (Gast)


Lesenswert?

ich glaube da brauche ich erst mal eine Weile bis ich mich da 
durchgekämpft habe. Aber ich werde sicher nochmal drauf zurückkommen.


>Mein Vorschlag - so habe ich das Problem dann meistens
>in den Griff bekommen:

>vor dem Label "Zeilenanfang" ein
>.db 0, 0
>oder
>.dw 0
>einschieben.
>Oder - worst case - ein
>.org 0x0A1B
Ich habe keine Ahnung welches Problem damit beseitigt werden soll?!

von Gast (Gast)


Lesenswert?

@Hannes Lux
> Das kann ich nicht bestätigen.
Das braucht es auch nicht.
Ich beschäftige mich seit 1997 mit AVR und Assembler und kenne die 
zahlreichen Bugs der diversen Versionen.

@pacer
> Ich habe keine Ahnung welches Problem damit beseitigt werden soll?!
ok. Dann habe ich hier irgendetwas falsch verstanden.
Ich ging anfangs davon aus, dass es ein Problem gäbe.

Wie z.B. der fehlerhafte Inhalt des X-pointers, 0x1432 statt 0x1436.
Mir ist das geschilderte Problem nicht unbekannt.
Daher habe beschrieben, wie ich es mitunter in den Griff
bekommen habe.
Egal, ob da wer bestätigt oder nicht. :-)

Kein Problem?
Wozu dann der ganze Thread? :-)
Ist immer wieder lustig hier.

von Gast (Gast)


Lesenswert?

vergesst meine Rede vor oben. :-)
passt alles.

es stimmt aber, dass AVR Assembler bisweilen
bei der Berechnung von Flashadressen über
Strings und Bytes ins Schleudern kamen.
Unabhängig von alignment-Problemen.

Lässt sich sogar in update-reports nachlesen.
Schönen Tag noch!

von Simon K. (simon) Benutzerseite


Lesenswert?

Gast schrieb:
> @Hannes Lux
>> Das kann ich nicht bestätigen.
> Das braucht es auch nicht.
> Ich beschäftige mich seit 1997 mit AVR und Assembler und kenne die
> zahlreichen Bugs der diversen Versionen.
Ganz schön vorlaut zu so einem Urgestein wie Hannes ;)

von Hannes L. (hannes)


Lesenswert?

Simon K. schrieb u.a.:

> Ganz schön vorlaut zu so einem Urgestein wie Hannes ;)

Ich werde es überleben... ;-)

...

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.