Tutorial Microcontroller MCS-51 ATMEL ISP

Pelatihan Mikrokontroller

 

Microcontroller Kits

Programmer and Target 89s51

Simple Mikrokontroller 89s51 Trainer


Standart
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

BACK