PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Simple Division mit AVR



martin
03.01.2006, 20:47
Hallo zusammen,

Ich habe eine ziemlich einfache Frage: Ich möchte mit einem Tiny26 eine 8-Bit Zahl durch eine 8-Bit Zahl teilen (Assembler). Für die 16/8 habe ich leider nicht mehr genügend Register. Mein Wertebereich erfordert das auch nicht. Momentan bin ich wohl zu blöd, im Internet oder hier im Forum passenden Code zu finden. Wenn mir bitte jemand weiterhelfen könnte...

Danke, Martin

Marco78
03.01.2006, 20:57
Würde es dir helfen, wenn ich das ganze mit Bascom schreibe und den Assemblercode poste?
Ich denke 16/8 (bit) geht da auch?!

martin
03.01.2006, 21:13
Danke für das Angebot, aber ich habe asm-Code für 16/8, der mir aber leider ein Register zuviel benutzt. Wird Bascom nicht anders machen, denke ich.

Grüsse, Martin

JanB
04.01.2006, 08:53
Hi Martin,
hier zwei Routinen aus einer ATMEL-AVR Applikation Note.
Einmal eine 8/8 Division ohne Vorzeichen (unsigned)
Einmal eine 8/8 Division mit Vorzeichen (signed)
Die verwendeten Register kannst du dir ja leicht selbst anpassen

Gruß Jan


;************************************************* **************************
;*
;* "div8u" - 8/8 Bit Unsigned Division
;*
;* This subroutine divides the two register variables "dd8u" (dividend) and
;* "dv8u" (divisor). The result is placed in "dres8u" and the remainder in
;* "drem8u".
;*
;* Number of words :14
;* Number of cycles :97
;* Low registers used :1 (drem8u)
;* High registers used :3 (dres8u/dd8u,dv8u,dcnt8u)
;*
;************************************************* **************************

;***** Subroutine Register Variables

.def drem8u =r15 ;remainder
.def dres8u =r16 ;result
.def dd8u =r16 ;dividend
.def dv8u =r17 ;divisor
.def dcnt8u =r18 ;loop counter

;***** Code

div8u: sub drem8u,drem8u ;clear remainder and carry
ldi dcnt8u,9 ;init loop counter
d8u_1: rol dd8u ;shift left dividend
dec dcnt8u ;decrement counter
brne d8u_2 ;if done
ret ; return
d8u_2: rol drem8u ;shift dividend into remainder
sub drem8u,dv8u ;remainder = remainder - divisor
brcc d8u_3 ;if result negative
add drem8u,dv8u ; restore remainder
clc ; clear carry to be shifted into result
rjmp d8u_1 ;else
d8u_3: sec ; set carry to be shifted into result
rjmp d8u_1



;************************************************* **************************
;*
;* "div8s" - 8/8 Bit Signed Division
;*
;* This subroutine divides the two register variables "dd8s" (dividend) and
;* "dv8s" (divisor). The result is placed in "dres8s" and the remainder in
;* "drem8s".
;*
;* Number of words :22
;* Number of cycles :103
;* Low registers used :2 (d8s,drem8s)
;* High registers used :3 (dres8s/dd8s,dv8s,dcnt8s)
;*
;************************************************* **************************

;***** Subroutine Register Variables

.def d8s =r14 ;sign register
.def drem8s =r15 ;remainder
.def dres8s =r16 ;result
.def dd8s =r16 ;dividend
.def dv8s =r17 ;divisor
.def dcnt8s =r18 ;loop counter

;***** Code

div8s: mov d8s,dd8s ;move dividend to sign register
eor d8s,dv8s ;xor sign with divisor
sbrc dv8s,7 ;if MSB of divisor set
neg dv8s ; change sign of divisor
sbrc dd8s,7 ;if MSB of dividend set
neg dd8s ; change sign of divisor
sub drem8s,drem8s ;clear remainder and carry
ldi dcnt8s,9 ;init loop counter
d8s_1: rol dd8s ;shift left dividend
dec dcnt8s ;decrement counter
brne d8s_2 ;if done
sbrc d8s,7 ; if MSB of sign register set
neg dres8s ; change sign of result
ret ; return
d8s_2: rol drem8s ;shift dividend into remainder
sub drem8s,dv8s ;remainder = remainder - divisor
brcc d8s_3 ;if result negative
add drem8s,dv8s ; restore remainder
clc ; clear carry to be shifted into result
rjmp d8s_1 ;else
d8s_3: sec ; set carry to be shifted into result
rjmp d8s_1

martin
04.01.2006, 10:30
Danke, sowas hab ich gesucht!

Martin

martin
04.01.2006, 18:42
Hallo nochmal,

ich hab mir eine "Minimalversion" gebastelt. Nicht besonders getestet, aber für meine Zwecke funktionierts:

"Poor man´s division" Kein Rest, kein nix. Für kleine Zahlen denke ich OK.
Ergebnis momentan in temp3 und temp1.



pmd: ;temp1/temp2 unsigned
clr temp3
pm1:
inc temp3
sub temp1, temp2
brcc pm1
mov temp1, temp3
ret


Ciao, Martin