Forum: Mikrocontroller und Digitale Elektronik Multiplikation ATMega32


von Daniel G. (sirdaniel)


Lesenswert?

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!

von Roland P. (pram)


Lesenswert?

du darfst r0 und r1 nicht so einfach verändern:

http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage

von Daniel G. (sirdaniel)


Lesenswert?

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!

von antworter (Gast)


Lesenswert?

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

von Daniel G. (sirdaniel)


Lesenswert?

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

von Roland P. (pram)


Lesenswert?

movw kann nur auf das ungerade Register (oder warens gerade) angewendet 
werden. das neben an liegende wird dann ebenfalls mit ge'mov'ed

von Roland P. (pram)


Lesenswert?

...
steht eigentlich da:

> Error: even register number required

also müsste

movw %0, r0

funktionieren.

von Daniel G. (sirdaniel)


Lesenswert?

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
Noch kein Account? Hier anmelden.