PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Multiplikation von Zahlen mit AVR



HiTech
17.11.2003, 00:57
Beispiel-Assemblercode:



Assembler Quelltext der Multiplikation

; Mult8.asm multipliziert zwei 8-Bit-Zahlen
; zu einem 16-Bit-Ergebnis
;
.NOLIST
.INCLUDE "C:\avrtools\appnotes\8515def.inc"
.LIST
;
; Ablauf des Multiplizierens:
;
; 1.Multiplikator 2 wird bitweise nach rechts in das
; Carry-Bit geschoben. Wenn es eine Eins ist, dann
; wird die Zahl in Multiplikator 1 zum Ergebnis dazu
; gezählt, wenn es eine Null ist, dann nicht.
; 2.Nach dem Addieren wird Multiplikator 1 durch Links-
; schieben mit 2 multipliziert.
; 3.Wenn Multiplikator 2 nach dem Schieben nicht Null
; ist, dann wird wie oben weiter gemacht. Wenn er Null
; ist, ist die Multplikation beendet.
;
; Benutzte Register
;
.DEF rm1 = R0 ; Multiplikator 1 (8 Bit)
.DEF rmh = R1 ; Hilfsregister für Multiplikation
.DEF rm2 = R2 ; Multiplikator 2 (8 Bit)
.DEF rel = R3 ; Ergebnis, LSB (16 Bit)
.DEF reh = R4 ; Ergebnis, MSB
.DEF rmp = R16 ; Hilfsregister zum Laden
;
.CSEG
.ORG 0000
;
rjmp START
;
START:
ldi rmp,0xAA ; Beispielzahl 1010.1010
mov rm1,rmp ; in erstes Multiplikationsreg
ldi rmp,0x55 ; Beispielzahl 0101.0101
mov rm2,rmp ; in zweites Multiplikationsreg
;
; Hier beginnt die Multiplikation der beiden Zahlen
; in rm1 und rm2, das Ergebnis ist in reh:rel (16 Bit)
;
MULT8:
;
; Anfangswerte auf Null setzen
clr rmh ; Hilfsregister leeren
clr rel ; Ergebnis auf Null setzen
clr reh
;
; Hier beginnt die Multiplikationsschleife
;
MULT8a:
;
; Erster Schritt: Niedrigstes Bit von Multplikator 2
; in das Carry-Bit schieben (von links Nullen nachschieben)
;
clc ; Carry-Bit auf Null setzen
ror rm2 ; Null links rein, alle Bits eins rechts,
; niedrigstes Bit in Carry schieben
;
; Zweiter Schritt: Verzweigen je nachdem ob eine Null oder
; eine Eins im Carry steht
;
brcc MULT8b ; springe, wenn niedrigstes Bit eine
; Null ist, über das Addieren hinweg
;
; Dritter Schritt: Addiere 16 Bits in rmh:rm1 zum Ergebnis
; in reh:rel (mit Überlauf der unteren 8 Bits!)
;
add rel,rm1 ; addiere LSB von rm1 zum Ergebnis
adc reh,rmh ; addiere Carry und MSB von rm1
;
MULT8b:
;
; Vierter Schritt: Multipliziere Multiplikator rmh:rm1 mit
; Zwei (16-Bit, links schieben)
;
clc ; Carry bit auf Null setzen
rol rm1 ; LSB links schieben (multiplik. mit 2)
rol rmh ; Carry in MSB und MSB links schieben
;
; Fünfter Schritt: Prüfen, ob noch Einsen im Multi-
; plikator 2 enthalten sind, wenn ja, dann weitermachen
;
tst rm2 ; alle bits Null?
brne MULT8a ; wenn nicht null, dann weitermachen
;
; Ende der Multiplikation, Ergebnis in reh:rel
;
; Endlosschleife
;
LOOP:
rjmp loop

17.11.2003, 11:10
Multiplikation mit der C-Control 1:

e=a*b

Basic ist halt doch einfacher
:-)
Ist natürlich langsamer, versteht sich

cht
11.06.2004, 16:46
Hab ich was falsch verstanden oder hast du dir die Mühe umsonst gemacht?
Der AVR-Befehlssatz enthält nämlich MUL (unsigned) und MULS (signed) für 8bit*8bit=16bit Multiplikationen. Man schreibt einfach
MUL r16, r17
und schon steht das Ergebnis im Word r1:r0.
Warum einfach, wenns auch umständlich geht?

mfG

cht

Kjion
11.06.2004, 16:51
Weil es mit den "alten" AVRs ( AT90S.... ) nur umständlich geht. Die haben nämlich den Hardware Multiplier wie er so schön heißt noch gar nicht...

Bei den "neuen" ( ab ATmega ) hast du natürlich recht, da macht das keine Sinn mehr :D

MfG Kjion