Forum: Mikrocontroller und Digitale Elektronik ADIW in kombination mit lo8 und hi8


von Wolfgang M. (procrash)


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

von Jobst M. (jobstens-de)


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

von hsb (Gast)


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.

von spess53 (Gast)


Lesenswert?

Hi

Außerdem dürfte ADIW an dieser Stelle sowieso fehl am Platz sein. Eine 
16-Bit Addition einer Konstante sieht so aus:
1
  add XL, lo8(physical_screen)
2
  adc XH, hi8(physical_screen)

MfG Spess

von (prx) A. K. (prx)


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? ;-)

von spess53 (Gast)


Lesenswert?

Hi

Mist. Man sollte vor dem zweiten Kaffee hier nichts schreiben. Hast 
natürlich recht.

MfG Spess

von Wolfgang M. (procrash)


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

von (prx) A. K. (prx)


Lesenswert?


von Wolfgang M. (procrash)


Lesenswert?

Hast recht, deutlich eleganter...

von Wolfgang M. (procrash)


Lesenswert?

Ne geht doch nicht. Da sagt mir der Compiler "expression too complex" 
wtf...

von spess53 (Gast)


Lesenswert?

Hi

>Ne geht doch nicht. Da sagt mir der Compiler "expression too complex"
>wtf...

Der Assembler vom AVR-Studio kann das problemlos.

MfG Spess

von Wolfgang M. (procrash)


Lesenswert?

gcc murrt. Finde schon noch raus woran es liegt...

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wolfgang Meyerle schrieb:
> gcc murrt. Finde schon noch raus woran es liegt...

Bei mir murrst nichts. Wie hast du physical_screen definiert?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

spess53 schrieb:
> Der Assembler vom AVR-Studio kann das problemlos.

Keine Kunst, das ist doch ein Absolutassembler.  Beim gas dagegen
muss das der Linker auflösen können, denn -physical_screen ist ein
verschieblicher Ausdruck.

von Wolfgang M. (procrash)


Lesenswert?

physical_screen ist als label bei mir im bss definiert.
Hab auch schon versucht das minus zeichen rauszuziehen, geht aber auch 
nicht...

von Wolfgang M. (procrash)


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...

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.