Hallo! Ich habe per InlineAssembler folgende kleine Routine zur Multiplikation zweier 8-Bit Zahlen geschrieben: static inline res Multi_8x8_8(uint8_t a, uint8_t b) { res r = {0, 0}; asm volatile ( "mul %2,%3 \n\t" // a * b "mov %0,r0 \n\t" // r0 nach r.res0 "mov %1,r1 \n\t" // r1 nach r.res1 :"=r" (r.res0), "=r" (r.res1) :"r" (a), "r" (b) ); return r; } Sie tut auch ihren Dienst, solange bis das Produkt von a und b nicht größer als 255 also 8Bit ist. Kommt das Produkt über diesen Wert hinaus löst der Controller ständig einen Reset aus (die Funktion wird nur einmalig aus der main-Fkt. heraus aufgerufen, nicht im Mainloop!). res ist eine Struktur welche zwei uint8_t Integers beeinhaltet (also die beiden Ergebnis-Werte). Vielen Dank für Eure Hilfe!
du darfst r0 und r1 nicht so einfach verändern: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage
Wieso nicht? Ich habe mich dabei exakt an die AppNote 201 von Atmel gehalten; da wird der Inhalt von r0 und r1 nach der Multiplikation auch per movw woanders hingeschoben (movw hat bei mir nicht funktioniert, edshalb die Alternative mit 2 x mov)! Könntest du das bitte ein wenig genauer erläutern? Vielen Dank!
Du solltest mal das von Roland verlinkte Dokument lesen: "r1 - assumed to be always zero in any C code, may be used to remember something for a while within one piece of assembler code, but must then be cleared after use (clr r1)."
OK, Problem behoben! Musste nur r1 noch löschen nach der ganzen Prozedur! Das steht auch in dem was du mir geschickt hast, Roland! Danke dafür! Aber hast du eine Idee weshalb ihc den movw-Befehl nicht verwenden kann, der Compiler gibt mir immer die folgenden Fehlermeldungen: Error: `,' required Error: even register number required Error: garbage at end of line "movw %0:%1,r0:r1 \n\t" Diese Zeile wird auch so assembliert wie ich mir das vorstelle wie es richtig sein müsste. Eine Idee? MFG
movw kann nur auf das ungerade Register (oder warens gerade) angewendet werden. das neben an liegende wird dann ebenfalls mit ge'mov'ed
...
steht eigentlich da:
> Error: even register number required
also müsste
movw %0, r0
funktionieren.
Hallo nochmal, Nachdem die 8x8-Multiplikation wunderbar funktioniert habe ich mich jetzt mal an die 16x16 gewagt: static inline res_32 Multi_16x16_32(uint16_t a, uint16_t b) { res_32 r = {0, 0, 0, 0}; asm volatile ( "clr r2 \n\t" "muls HIGH(%4), HIGH(%5) \n\t" "movw r18, r0 \n\t" "mul LOW(%4), LOW(%5) \n\t" "movw r16, r0 \n\t" "mulsu HIGH(%4), LOW(%5) \n\t" "sbc r19, r2 \n\t" "add r17, r0 \n\t" "adc r18, r1 \n\t" "adc r19, r2 \n\t" "mulsu HIGH(%5), LOW(%4) \n\t" "sbc r19, r2 \n\t" "add r17, r0 \n\t" "adc r18, r1 \n\t" "adc r19, r2 \n\t" "movw %0, r16 \n\t" "movw %2, r18 \n\t" "clr r1" :"=&r" (r.res0), "=&r" (r.res1), "=&r" (r.res2), "=&r" (r.res3) :"d" (a), "d" (b) ); return r; } Jetzt beschwert sich der Assembler in der Form Error: constant value required Error: register number above 15 required Error: `,' required Error: garbage at end of line für jede Zeile in der HIGH() bzw. LOW() vorkommt. Was mache ich da falsch? Wie muss ich denn sonst getrennt auf High- bzw. Lowbyte zugreifen? MFG Daniel
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.