ADIW in kombination mit lo8 und hi8

OP #2720523
Lesenswert?

Hallo,

weiss jemand von euch zufälligerweise warum adiw in Kombination mit den 
Makros lo8 und hi8 nicht funktioniert?

Ich habe da folgende Codezeilen und mein Kompiler meckert:

...
  adiw XL, lo8(physical_screen)
  add XH, hi8(physical_screen)
...

Eigentlich sollte das was bei dem lo8 Makro rauskommt doch eine Adresse 
sein die fix ist.

Jetzt hab ich mal im Forum etwas gesucht und bin darauf gestossen dass
ADIW Rdl, K mit 0<=k<=63 sein muss.

Diesen Sachverhalt finde ich im Datenblatt des Atmega2560 leider nicht 
und würde jetzt gerne wissen ob das Tatsächlich so ist und wenn wieso? 
Macht doch eigentlich nur Sinn bei ner 8 Bit Addition K zwischen 0 und 
255 zuzulassen oder sehe ich da was falsch?

Grüße

Wolfgang
#2720528
Lesenswert?

Wolfgang Meyerle schrieb:
> Diesen Sachverhalt finde ich im Datenblatt des Atmega2560 leider nicht
> und würde jetzt gerne wissen ob das Tatsächlich so ist und wenn wieso?

Hmmm ... eigentlich steht dort gar nicht viel über die Befehle. 
Vielleicht hat er ja gar keine. Wo mag das nur stehen? :-)



ADIW – Add Immediate to Word

Description:

Adds an immediate value (0 - 63) to a register pair and places the 
result in the register pair. This instruction operates on the upper four 
register pairs, and is well suited for operations on the pointer 
registers.
This instruction is not available in all devices.

http://www.atmel.com/Images/doc0856.pdf


Gruß

Jobst
Gast #2720535
Lesenswert?

Der Erläuterung des Befehlsatzes steht auf jeden Fall in den 
allgeimeinen Unterlagen zum AVR-Core, die man immer zusaätzlich zu den 
des spezifischen Typs konsultieren sollte.

Bei genauer Betrachtung siehst Du dann, dass alle Befehle in einem 
16-Bit Wort codiert sind, und die Konstante (das was Du addierst) 
ebenfalls MIT IM OPCODE liegt. Das ist für ergraute Absolventen (nicht 
pers. gemeint) alter Schule (Z80/6502/etc.) gewöhnungsbedürfig, aber 
absolut gängig bei heutigen Controllern.

Im Opcode des AVR-ADIW waren schlichtweg nicht mehr als 6 Bit für die 
Konstante frei, daher der knappe Wertebereich.
#2720539
Lesenswert?

Genauer: Sie sähe ungefähr so aus, wenn es diese Befehle mit Konstante 
als Operand geben würde. Weil es sie aber nicht gibt weicht man meist 
auf die Subtraktion aus:
  subi XL, lo8(-physical_screen)
  sbci XH, hi8(-physical_screen)

Nanu spess53, war die Nacht zu lang oder ist der Morgen zu früh? ;-)
OP #2720699
Lesenswert?

Ah alles klar,

das mit dem Opcode macht Sinn. Verstehe jetzt auch warum das nur bis 
maximal 63 addiert werden kann...

Das mit dem:
 add XL, lo8(physical_screen)
 adc XH, hi8(physical_screen)

geht so meines Wissens allerdings nicht.
Ich kann add und adc nur in Kombination mit Registern verwenden

also wenn dann so:

ldi r18, lo8(physical_screen)
add XL, r18
ldi r19, hi8(physical_screen)
adc XH, r18

Deswegen dachte ich auch wäre es auch praktisch einen Befehl zu nehmen 
der gleich einen Immediate addieren kann, vorzugsweise mit Übertrag für 
16 Bit Register, aber naja...

Danke jedenfalls,

Wolfgang
OP #2720851
Lesenswert?

So jetzt hab ichs...

  subi XL, lo8(-(physical_screen))
    sbci XH, hi8(-(physical_screen))

Das label muss noch eingeklammert werden, sonst bringt GCC folgende 
Fehlermeldung:
../src/driver.S:230: Error: can't resolve `0' {.bss section} - 
`physical_screen' {.bss section}
../src/driver.S:230: Error: expression too complex

Danke trotzdem nochmal...

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