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
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
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.
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
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? ;-)
Hi Mist. Man sollte vor dem zweiten Kaffee hier nichts schreiben. Hast natürlich recht. MfG Spess
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
Wolfgang Meyerle schrieb: > also wenn dann so: Eher so: Beitrag "Re: ADIW in kombination mit lo8 und hi8"
Ne geht doch nicht. Da sagt mir der Compiler "expression too complex" wtf...
Hi >Ne geht doch nicht. Da sagt mir der Compiler "expression too complex" >wtf... Der Assembler vom AVR-Studio kann das problemlos. MfG Spess
Wolfgang Meyerle schrieb: > gcc murrt. Finde schon noch raus woran es liegt... Bei mir murrst nichts. Wie hast du physical_screen definiert?
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.
physical_screen ist als label bei mir im bss definiert. Hab auch schon versucht das minus zeichen rauszuziehen, geht aber auch nicht...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.