Guten Abend, robo_wolf!

Zitat Zitat von robo_wolf
Ich glaub, ich steh hier schon wieder auf der Leitung.
nee, stehst Du nicht: Du bist nur über die Gemeinheiten der Speicherorganisation bei ATMELs MCs gestolpert.

Guck' mal:
Zitat Zitat von robo_wolf
0x0019 CD AB
Offenbar ist im Flash-Speicher unter jeder Adresse je ein 2-Byte-Wort gespeichert.
Deshalb ist der Programmzähler (PC) so aufgebaut, dass PC+1 auf das nächste 2-Byte-Wort nach PC zeigt. Beim Inkrementieren springt der PC um zwei Bytes weiter. So sind auch die Adresse 0x0019 aus Deinem Beispiel zu verstehen: Es ist die Adresse eines 2-Byte-Wortes.

Im Gegensatz dazu ist im RAM unter jeder Adresse je ein 1-Byte-Wort gespeichert.
Deshalb sind die Zeigerregister zh:zl, yh:yl und xhl so aufgebaut, dass sie beim Inkrementieren um ein 1-Byte-Wort weiterspringen.

Beim Auslesen des Flash-Speichers mit der „lpm“-Anweisung muss man zh:zl als Zeigerregister verwenden. Das führt zu Schwierigkeiten: zh:zl kann nur auf einzelne Bytes zeigen, die Flashspeicher-Adressen beziehen sich aber immer auf ein 2-Byte-Wort. Also muss man die Flashadresse in zh:zl verdoppeln, dann zeigt zh:zl auf das LSB des gespeicherten Doppelbytes.

Beispiel: Das MSB des unter 0x0019 im Flash gespeicherten Wortes soll ausgelesen werden

Code:
     ldi zh,HIGH(0x0019)
     ldi zl,LOW(0x0019)
     add zl,zl                 ;  Zeiger verdoppeln
     adc zh,zh                ; jetzt zeigt er auf das LSB
;     lpm r16,z               ; diese Anweisung würde jetzt das LSB (0xCD) nach r16 befördern
     adiw zh:zl,0x0001        ; wir wollen ans MSB kommen, also noch eins draufaddieren
     lpm r16,z                ; so, jetzt landet das MSB (0xAB) in r16.
Du hast also recht: Der PC zeigt auf gerade wie ungerade Adressen im Flashspeicher. Ich bezog mich auf die Verwendung von zh:zl im Flashspeicher. Da steht das LSB immer unter der geraden Adresse und das MSB unter der ungeraden.

Am Besten, Du probierst's direkt im Simulator und mit einem Glas Wein gleich 'mal aus .

Ciao,

mare_crisium