![]() |
|||
Microcontroller Kits Simple
Mikrokontroller 89s51 Trainer
Super
Mikrokontroller Trainer 89s51
|
Subroutine Division for 8051 Microcontroller
;=============================================================== ; subroutine DIV8 ; 8-Bit / 8-Bit to 8-Bit Quotient & Remainder signed Divide ; 2's Complement Format ; ; input: r0 = Dividend X ; r1 = Divisor Y ; ; output: r0 = quotient Q of division Q = X / Y ; r1 = remainder ; ; calls: Cr0, Cr1, Mr0-> See previous subroutine ; alters: acc, C, Bits 21H & 22H ;=============================================================== DIV8: anl PSW, #0E7H ; Register Bank 0
acall Cr0 ; 2's comp -> Mag/Sign
acall Cr1 ; 2's comp -> Mag/Sign
acall UDIV8
acall Mr0 ; Mag/Sign -> 2's Comp
ret
;=============================================================== ; subroutine UDIV8 ; 8-Bit / 8-Bit to 8-Bit Quotient & Remainder Unsigned Divide ; ; input: r0 = Dividend X ; r1 = Divisor Y ; ; output: r0 = quotient Q of division Q = X / Y ; r1 = remainder ; ; ; alters: acc, C ;=============================================================== UDIV8: push b
mov a, r0 ; read X and ...
mov b, r1 ; ... Y
div ab ; divide X and Y
mov r0, a ; save result quotient
mov r1, b ; save remainder
pop b
ret
;====================================================================
; subroutine DIV16
; 16-Bit / 16-Bit to 16-Bit Quotient & remainder signed Divide
; 2's Complement Format
;
; input: r1, r0 = Dividend X
; r3, r2 = Divisor Y
;
; output: r1, r0 = quotient Q of division Q = X / Y
; r3, r2 = remainder
; Carry C is set if Y = 0, i.e. divide by 0 attempted
;
; calls: UDIV16, Cr0r1, Cr2r3, Mr0r1
;
; alters: acc, r4, r5, r6, r7, flags, Bits 21H & 22H
;====================================================================
DIV16: anl PSW, #0E7H ; Register Bank 0
mov a, r3 ; get divisor high byte
orl a, r2 ; OR with low byte
jnz div_OK ; divisor OK if not 0
setb C ; else, overflow
ret
div_OK: push dpl
push dph
push b
acall Cr0r1 ; 2's comp -> Mag/Sign
acall Cr2r3 ; 2's comp -> Mag/Sign
acall UDIV16
acall Mr0r1 ; Mag/Sign -> 2's Comp
clr C
pop b
pop dph
pop dpl
ret ; done
;====================================================================
; subroutine UDIV16
; 16-Bit / 16-Bit to 16-Bit Quotient & Remainder Unsigned Divide
;
; input: r1, r0 = Dividend X
; r3, r2 = Divisor Y
;
; output: r1, r0 = quotient Q of division Q = X / Y
; r3, r2 = remainder
;
; alters: acc, B, dpl, dph, r4, r5, r6, r7, flags
;====================================================================
UDIV16: mov r7, #0 ; clear partial remainder
mov r6, #0
mov B, #16 ; set loop count
div_loop: clr C ; clear carry flag
mov a, r0 ; shift the highest bit of
rlc a ; the dividend into...
mov r0, a
mov a, r1
rlc a
mov r1, a
mov a, r6 ; ... the lowest bit of the
rlc a ; partial remainder
mov r6, a
mov a, r7
rlc a
mov r7, a
mov a, r6 ; trial subtract divisor
clr C ; from partial remainder
subb a, r2
mov dpl, a
mov a, r7
subb a, r3
mov dph, a
cpl C ; complement external borrow
jnc div_1 ; update partial remainder if
; borrow
mov r7, dph ; update partial remainder
mov r6, dpl
div_1: mov a, r4 ; shift result bit into partial
rlc a ; quotient
mov r4, a
mov a, r5
rlc a
mov r5, a
djnz B, div_loop
mov a, r5 ; put quotient in r0, and r1
mov r1, a
mov a, r4
mov r0, a
mov a, r7 ; get remainder, saved before the
mov r3, a ; last subtraction
mov a, r6
mov r2, a
ret
;====================================================================
; subroutine DIV32
; 32-Bit / 16-Bit to 32-Bit Quotient & remainder signed Divide
; 2's Complement Format
;
; input: r3, r2, r1, r0 = Dividend X
; r5, r4 = Divisor Y
;
; output: r3, r2, r1, r0 = quotient Q of division Q = X / Y
; r7, r6, r5, r4 = remainder
; Carry C is set if Y = 0, i.e. divide by 0 attempted
;
; calls: UDIV32, Cr0r3, Cr4r5, Mr0r3
;
; alters: acc, flags, Bits 21H & 22H
;====================================================================
DIV32: anl PSW, #0E7H ; Register Bank 0
mov a, r4 ; get divisor high byte
orl a, r5 ; OR with low byte
jnz div32_OK ; divisor OK if not 0
setb C ; else, overflow
ret
div32_OK: acall Cr0r3 ; 2's comp -> Mag/Sign
acall Cr4r5 ; 2's comp -> Mag/Sign
acall UDIV32
acall Mr0r3 ; Mag/Sign -> 2's Comp
clr C ; divisor is not 0
ret ; done
;====================================================================
; subroutine UDIV32
; 32-Bit / 16-Bit to 32-Bit Quotient & Remainder Unsigned Divide
;
; input: r3, r2, r1, r0 = Dividend X
; r5, r4 = Divisor Y
;
; output: r3, r2, r1, r0 = quotient Q of division Q = X / Y
; r7, r6, r5, r4 = remainder
;;
; alters: acc, flags
;====================================================================
UDIV32: push 08 ; Save Register Bank 1
push 09
push 0AH
push 0BH
push 0CH
push 0DH
push 0EH
push 0FH
push dpl
push dph
push B
setb RS0 ; Select Register Bank 1
mov r7, #0 ; clear partial remainder
mov r6, #0
mov r5, #0
mov r4, #0
mov B, #32 ; set loop count
div_lp32: clr RS0 ; Select Register Bank 0
clr C ; clear carry flag
mov a, r0 ; shift the highest bit of the
rlc a ; dividend into...
mov r0, a
mov a, r1
rlc a
mov r1, a
mov a, r2
rlc a
mov r2, a
mov a, r3
rlc a
mov r3, a
setb RS0 ; Select Register Bank 1
mov a, r4 ; ... the lowest bit of the
rlc a ; partial remainder
mov r4, a
mov a, r5
rlc a
mov r5, a
mov a, r6
rlc a
mov r6, a
mov a, r7
rlc a
mov r7, a
mov a, r4 ; trial subtract divisor from
clr C ; partial remainder
subb a, 04
mov dpl, a
mov a, r5
subb a, 05
mov dph, a
mov a, r6
subb a, #0
mov 06, a
mov a, r7
subb a, #0
mov 07, a
cpl C ; complement external borrow
jnc div_321 ; update partial remainder if
; borrow
mov r7, 07 ; update partial remainder
mov r6, 06
mov r5, dph
mov r4, dpl
div_321: mov a, r0 ; shift result bit into partial
rlc a ; quotient
mov r0, a
mov a, r1
rlc a
mov r1, a
mov a, r2
rlc a
mov r2, a
mov a, r3
rlc a
mov r3, a
djnz B, div_lp32
mov 07, r7 ; put remainder, saved before the
mov 06, r6 ; last subtraction, in bank 0
mov 05, r5
mov 04, r4
mov 03, r3 ; put quotient in bank 0
mov 02, r2
mov 01, r1
mov 00, r0
clr RS0
pop B
pop dph
pop dpl
pop 0FH ; Retrieve Register Bank 1
pop 0EH
pop 0DH
pop 0CH
pop 0BH
pop 0AH
pop 09
pop 08
ret
Comments, questions and discussion about this topic
|
||