8051 Divide 32bits by 16bits

by Andrew David, Software Manager, Ultronics Ltd http://www.Ultronics.com
; Divide 16 bit number in R7,R6 by 8 bit number in B. Put result in A.

div16:  CJNE  R6,#0,calcdiv
        CJNE  R7,#0,calcdiv
        MOV   R2,#0             ; If R7:R6 is 0, then result is 0
        LJMP  dend

calcdiv:CLR   C
        MOV   A,B
        RRC   A
        MOV   R5,A

        MOV   A,#0
        RRC   A
        MOV   R4,A              ; R5,R4 is the initial divisor

        MOV   R2,#0             ; Result
        MOV   R3,#80h           ; Bit value for result

dloop:  MOV   A,R6
        CLR   C
        SUBB  A,R4              ; LS Byte subtract
        MOV   R1,A

        MOV   A,R7
        SUBB  A,R5              ; MS Byte subtract
        JC    set0              ; If carry set, subtract was not possible

        MOV   R7,A
        MOV   A,R1
        MOV   R6,A              ; R7,R6 is the new value to subtract from

        MOV   A,R2
        ADD   A,R3
        MOV   R2,A              ; Set bit in result

set0:   CLR   C
        MOV   A,R3
        RRC   A
        MOV   R3,A              ; New bit value for result
        JZ    dend              ; all bits have been done

        CLR   C
        MOV   A,R5
        RRC   A
        MOV   R5,A
        MOV   A,R4
        RRC   A
        MOV   R4,A              ; R5,R4 is new divisor

        LJMP  dloop             ; do next bit

dend:   MOV   A,R2              ; Result in A
        RET






; Divide 20 bit number in R7:R6:R5 by 10 bit number in R3:R2.
; Put result in A:B.

div20:  MOV   A,R5
        ORL   A,R6
        ORL   A,R7
        JNZ   caldiv

        SETB  RS0               ; Reg bank 1
        MOV   R7,#0
        MOV   R6,#0             ; If R7:R6:R5 is 0, then result is 0
        CLR   RS0               ; Reg bank 0
        LJMP  d20end

caldiv: MOV   R4,#0
        MOV   R1,#3             ; Divisor is already 6 left. Shift another
3.

shftsub:CLR   C
        MOV   A,R2
        RLC   A
        MOV   R2,A
        MOV   A,R3
        RLC   A
        MOV   R3,A
        MOV   A,R4
        RLC   A
        MOV   R4,A
        DJNZ  R1,shftsub        ; R4:R3:R2 is the initial sutractor

        SETB  RS0               ; Reg bank 1
        MOV   R7,#0
        MOV   R6,#0             ; Result in R7:R6 bank 1
        MOV   R5,#80h
        MOV   R4,#0             ; Bit value for result in R5:R4 bank 1
        CLR   RS0               ; Reg bank 0

d20loop:CLR   C
        MOV   A,R5
        SUBB  A,R2              ; LS Byte subtract
        MOV   R0,A

        MOV   A,R6
        SUBB  A,R3              ; Mid Byte subtract
        MOV   R1,A

        MOV   A,R7
        SUBB  A,R4              ; MS Byte subtract
        JC    res0              ; If carry set, subtract was not possible

        MOV   R7,A
        MOV   A,R1
        MOV   R6,A
        MOV   A,R0
        MOV   R5,A              ; Update subtractee

        SETB  RS0               ; Reg bank 1
        MOV   A,R6
        ORL   A,R4
        MOV   R6,A              ; Set bit in result LS Byte
        MOV   A,R7
        ORL   A,R5
        MOV   R7,A              ; Set bit in result MS Byte

res0:   SETB  RS0               ; Reg bank 1
        CLR   C
        MOV   A,R5
        RRC   A
        MOV   R5,A
        MOV   A,R4
        RRC   A
        MOV   R4,A              ; New bit value for result
        ANL   A,#20h
        CLR   RS0               ; Reg bank 0
        JNZ   d20end            ; all bits have been done

        CLR   C
        MOV   A,R4
        RRC   A
        MOV   R4,A
        MOV   A,R3
        RRC   A
        MOV   R3,A
        MOV   A,R2
        RRC   A
        MOV   R2,A              ; R4:R3:R2 is the new subtractor

        LJMP  d20loop           ; do next bit

d20end: SETB  RS0               ; Reg bank 1
        MOV   A,R7
        MOV   B,R6              ; Result in A:B
        CLR   RS0               ; Reg bank 0

        RET

See: