AVR Arithmetik
;
; Vergleiche < r16, r17 > mit < r20, r21 >
;
cp r16, r20
cpc r17, r21 |
;
; Vergleiche < r16, r17, r18, r19 > mit < r20, r21, r22, r23 >
;
cp r16, r20
cpc r17, r21
cpc r18, r22
cpc r19, r23 |
;
; < r16, r17 > = < r16, r17 > + < r20, r21 >
;
add r16, r20
adc r17, r21 |
;
; < r16, r17, r18, r19 > = < r16, r17, r18, r19 > + < r20, r21, r22, r23 >
;
add r16, r20
adc r17, r21
adc r18, r22
adc r19, r23 |
;
; < r16, r17 > = < r16, r17 > - < r20, r21 >
;
sub r16, r20
sbc r17, r21 |
;
; < r16, r17, r18, r19 > = < r16, r17, r18, r19 > - < r20, r21, r22, r23 >
;
sub r16, r20
sbc r17, r21
sbc r18, r22
sbc r19, r23 |
Ergebnis gerundet, und mit Restbildung
.def a0 = r16
.def a1 = r17
.def a2 = r18
.def a3 = r19
.def b0 = r20
.def b1 = r21
.def b2 = r22
.def b3 = r23
.def t0 = r24
.def t1 = r25
.def t2 = r26
.def t3 = r27
.def t4 = r28
;************************************************************************
;* *
;* unsigned rounded division 32 bit *
;* *
;************************************************************************
urdiv32:
mov t0, b0 ;T = B
mov t1, b1
mov t2, b2
mov t3, b3
lsr t3 ;B / 2
ror t2
ror t1
ror t0
add a0, t0 ;A = A + B / 2
adc a1, t1
adc a2, t2
adc a3, t3
;************************************************************************
;* *
;* unsigned division 32 bit *
;* *
;************************************************************************
; a3..0 = a3..0 / b3..0
; b3..0 = remainde
;cycle: max 684
udiv32:
clr t0
clr t1
clr t2
clr t3
ldi t4, 32
udi1: lsl a0
rol a1
rol a2
rol a3
rol t0
rol t1
rol t2
rol t3
cp t0, b0
cpc t1, b1
cpc t2, b2
cpc t3, b3
brcs udi2
sub t0, b0
sbc t1, b1
sbc t2, b2
sbc t3, b3
inc a0
udi2: dec t4
brne udi1
mov b0, t0
mov b1, t1
mov b2, t2
mov b3, t3
ret |
.def a0 = r16
.def a1 = r17
.def a2 = r18
.def a3 = r19
.def b0 = r20
.def b1 = r21
.def b2 = r22
.def b3 = r23
.def t0 = r24
.def t1 = r25
.def t2 = r26
.def t3 = r27
;************************************************************************
;* *
;* unsigned rounded division 32 bit *
;* *
;************************************************************************
urdiv32:
mov t0, b0 ;T = B
mov t1, b1
mov t2, b2
mov t3, b3
lsr t3 ;B / 2
ror t2
ror t1
ror t0
add a0, t0 ;A = A + B / 2
adc a1, t1
adc a2, t2
adc a3, t3
;************************************************************************
;* *
;* unsigned division 32 bit *
;* *
;************************************************************************
;cycle: max 431 (63%) (684)
udiv32:
clr t1
tst b3
breq udi10
ldi t0, 8
udi1: lsl a0
rol a1
rol a2
rol a3
rol t1
cp a1, b0
cpc a2, b1
cpc a3, b2
cpc t1, b3
brcs udi2
sub a1, b0
sbc a2, b1
sbc a3, b2
sbc t1, b3
inc a0
udi2: dec t0
brne udi1
mov b0, a1
clr a1
mov b1, a2
clr a2
mov b2, a3
clr a3
mov b3, t1
ret
udi10: tst b2
breq udi20
ldi t0, 16
udi11: lsl a0
rol a1
rol a2
rol a3
rol t1
brcs udi12
cp a2, b0
cpc a3, b1
cpc t1, b2
brcs udi13
udi12: sub a2, b0
sbc a3, b1
sbc t1, b2
inc a0
udi13: dec t0
brne udi11
mov b0, a2
clr a2
mov b1, a3
clr a3
mov b2, t1
ret
udi20: tst b2
breq udi30
ldi t0, 24
udi21: lsl a0
rol a1
rol a2
rol a3
rol t1
brcs udi22
cp a3, b0
cpc t1, b1
brcs udi23
udi22: sub a3, b0
sbc t1, b0
inc a0
udi23: dec t0
brne udi21
mov b0, a3
clr a3
mov b1, t1
ret
udi30: ldi t0, 32
udi31: lsl a0
rol a1
rol a2
rol a3
rol t1
brcs udi32
cp t1, b0
brcs udi33
udi32: sub t1, b0
inc a0
udi33: dec t0
brne udi31
mov b0, t1 ;store remainder
ret
;------------------------------------------------------------------------ |
.def a0 = r16
.def a1 = r17
.def a2 = r18
.def a3 = r19
.def b0 = r20
.def b1 = r21
.def b2 = r22
.def b3 = r23
.def t0 = r24
.def t1 = r25
.def t2 = r26
.def t3 = r27
.def i0 = r28
;************************************************************************
;* *
;* unsigned multiplication 32 bit *
;* *
;************************************************************************
;cycle: max 245
umul32:
cpi a3, 0
cpc a3, a2
breq _umu1 ;one operand must be below 65536
mov t0, a0 ; swap A <-> B
mov a0, b0
mov b0, t0
mov t0, a1
mov a1, b1
mov b1, t0
mov b2, a2
mov b3, a3
clr a2
clr a3
; a3,2,1,0 = a1,0 * b3,2,1,0
_umu1: ldi i0, 16
clr t0
clr t1
ror a1
ror a0
_umu2: brcc _umu3
add a2, b0
adc a3, b1
adc t0, b2
adc t1, b3
_umu3: ror t1
ror t0
ror a3
ror a2
ror a1
ror a0
dec i0
brne _umu2
ret
;------------------------------------------------------------------------ |
; WURZEL 32Bit
; 04/2006
; Bernhard.Erfurt@gmx.de
; ATmega8
.include "m8def.inc"
.def temp = R16 ; TEMP
.def temp1 = R17 ; TEMP1
.def temp2 = R18 ; TEMP2
.def temp3 = R19 ; TEMP3
.def temp4 = R20 ; TEMP4
;STACK initialisieren
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp
LOOP:
; TESTZAHLEN
ldi temp1, BYTE1(10000)
ldi temp2, BYTE2(10000)
ldi temp3, BYTE3(10000)
ldi temp4, BYTE4(10000)
; WURZEL berechnen
rcall WURZEL_32 ; INP: TEMP1...4 OUT: TEMP1...2
nop
rjmp LOOP
;#######################################################################
;
; INPUT temp1 (LOW)
; INPUT temp2
; INPUT temp3
; INPUT temp4 (HIGH)
;
; OUTPUT temp1 (LOW)
; OUTPUT temp2 (HIGH)
;
; Hilfsregister: R0,R1,R14,R15,R16,R21,R22,R23,R24
;
; rcall WURZEL_32 ; INP: TEMP1...4 OUT: TEMP1...2
;
WURZEL_32:
; HILFSREGISTER sichern (STACK)
push R0
push R1
push R14
push R15
push R16
push R21
push R22
push R23
push R24
; HILFSREGISTER initialisieren
ldi temp, 1
mov R14, temp ;= 1
ldi temp, 2
mov R15, temp ;= 2
clr temp
clr r0 ; ERGEBNIS
clr r1
ldi r21,1 ;= 1
clr r22
clr r23
clr r24
; Wurzel-Berechnung
WURZEL_32_w:
sub temp1,R21 ; SUBTRAKTION
sbc temp2,R22
sbc temp3,R23
sbc temp4,R24
brlo WURZEL_32_ww
add R0,R14 ; ADDITION +1(Ergebnis)
adc R1,temp
add R21,R15 ; ADDITION +2
adc R22,temp
adc R23,temp
adc R24,temp
rjmp WURZEL_32_w
WURZEL_32_ww:
mov temp1,r0 ; ERGEBNIS KOPIEREN
mov temp2,r1
; HILFSREGISTER wieder herstellen (STACK)
pop R24
pop R23
pop R22
pop R21
pop R16
pop R15
pop R14
pop R1
pop R0
ret |
Schnelle Implementierung für große Operanden: http://www.mikrocontroller.net/topic/98432
[bearbeiten] Binär zu BCD - Umwandlung
Zur Ausgabe einer Binärzahl auf ein Textdisplay oder zur seriellen ASCII-Übertragung an den PC ist diese Umwandlung nötig. Sie ist ähnlich aufwendig wie eine Division, zum Beispiel für eine 32-Bit-Zahl etwa 500-900 Taktzyklen und 10 Register.
Mehrere Verfahren werden angeboten:
Für eine Division pro Dezimalstelle ist nur ein Unterprogramm nötig. Der Divisionsrest, engl. remainder, bildet unmittelbar die BCD-codierte Dezimalziffer, von rechts nach links fortschreitend. Zur Ausgabe von links nach rechts kann man die Ziffern auf dem Stack zwischenlagern (LIFO-Register last-in first-out)
Beispiele:
[bearbeiten] Division /10000, /1000, /100, /10
ähnlich dem vorigen, aber die BCD-Ziffern erscheinen sofort von links nach rechts.
Beispiele:
Hier wird die Binärzahl, mit der höchstwertigen Stelle voran, von rechts in die Ergebnisregister geschoben. Nach jedem Schiebevorgang wird eine Korrekturrechnung ausgeführt. Für 32 Bit bilden 4 Eingabe- und 5 Ausgaberegister ein 72 Bit Schieberegister, das 32 mal links geschoben wird.
Durch die Korrekturrechnung wird die Binärzahl zur gepackten (2 Stellen pro Byte) BCD-Zahl "aufgebläht".
Eine Erklärung des Algorithmus soll hier versucht werden:
Um die niederwertigste 4 Bit Binärziffer in BCD umzuwandeln, ist für $0...$9 keine Änderung nötig, für $A...$F wird "6" addiert. Diese Addition wird ersetzt durch eine Addition von "3" und anschließendes Linksschieben. Das führt man zunächst für beide Halbbytes gleichzeitig mit "subi Reg,-$33" aus. Anschließend werden die beiden Additionen einzeln für den Fall "0...9" rückgängig gemacht. Die Bits 4 und 7 des Registers dient dabei als BCD-Carry-Flag (Halbbyte-Übertrag). Das normale C-Flag wird durch die Additionen nicht beeinflußt, es dient nur dem Schiebevorgang.
Beispiele:
Für kleine Zahlen kann die gesuchte BCD-Zahl auch aus einer Tabelle entnommen werden.
Eine Mischung mehrerer Verfahren wird z.B. von Andre Birua in der ersten Variante von "Bin4BCD" verwendet. Die oberen 16 Bit werden nach "Div/10000" vorbearbeitet und anschließend alle 32 Bit nach "Add $33".
enthält C-Code und PIC-Code für schnelle 16 Bit Wandlung, Hardware-Multiplizierer möglich - auch für FPGA interessant
[bearbeiten] Diskussionsbeiträge im Forum
|