Category : Assembly Language Source Code
Archive   : ASM_SUBR.ZIP
Filename : MBINDIV

 
Output of file : MBINDIV contained in archive : ASM_SUBR.ZIP
;-------------------------mbindiv routine begins--------------------------+
; from BLUEBOOK OF ASSEMBLY ROUTINES FOR IBM PC & XT.
; page : 122
;
; NAME MBINDIV
;
; ROUTINE FOR Multidigit Binary DIVISION
;
; FUNCTION: This routine divides two multidigit binary numbers, producing
; both a quotient and remainder.
;
; INPUT: Upon entry DS:SI points to the divisor; DS:BX points to where
; the dividend is upon entry and where the remainder will be upon exit,
; and DS:DI points to the location where the quotient will be upon exit.
; The size of these multidigit numbers is controlled by the constant
; ISIZE. The divisor and quotient contain 16*ISIZE number of
; bits and the dividend and remainder have double that precision.
; Both the divisor and the quotient are stored in ISIZE number of 16-bit
; words of memory and the dividend and remainder are stored in 2*ISIZE
; number of 16-bit words of memory.
;
; OUTPUT: Upon exit DS:BX points to where the quotient is stored and
; DS:DI points to where the remainder is stored.
;
; REGISTERS USED: No registers are modified.
;
; SEGMENTS REFERENCED: Upon entry the data segment must contain
; storage for the multidigit numbers described above.
;
; ROUTINES CALLED: None
;
; SPECIAL NOTES: None
;
; LOCAL SUBROUTINE TO COMPARE DIVISOR AGAINST DIVIDEND
;
divcmp proc near
;
push si ; save registers
push di
push cx
;
std ; backward direction
add si,4*isize-2 ; point to end of temp divisor
add di,4*isize-2 ; point to end of quotient
mov cx,2*isize ; count for double precision
;
repz cmpsw ; compare 'digit' by 'digit'
;
pop cx ; restore registers
pop di
poop si
ret ; return from divcmp
;
; LOCAL SUBROUTINE FOR ARITHMETIC SHIFT DIVISOR LEFT
;
divsal proc near
;
push si ; save registers
push cx
;
mov cx,2*isize ; set counter
clc ; clear carry in
;
divsal1:
rcl word ptr [si],1 ; shift one word by one bit
inc si ; point to next word
inc si
loop divsal1 ; loop through entire divisor
;
pop cx ; restore registers
pop si
ret ; return from divsal
;
divsal endp
;
; LOCAL SUBROUTINE FOR LOGICAL SHIFT DIVISOR RIGHT
;
divslr proc near
;
push si ; save registers
push cx
;
add si,4*isize-2 ; poin to end of temp divisor
mov cx,2*isize ; count for double precision
clc ; clear carry in
;
divslr1:
rcr word ptr [si],1 ; shift one word by one bit
inc si ; point to next word
inc si
loop divslr1 ; loop through entire divisor
;
pop cx ; restore registers
pop si
ret ; return from divslr
;
divslr endp
;
; LOCAL SUBROUTINE TO SUBTRACT SHIFTED DIVISOR FROM DIVIDEND
;
divsub proc near
;
push si ; save registers
push di
push cx
;
clc ; clear carry in
mov cx,2*isize ; set count fop double precision
;
divsub1:
mov ax,[si] ; get word from shifted divisor
inc si ; point to next word
inc si
sbb [di],ax ; subtract from word of dividend
inc di ; point to next word
inc di
loop divsub1 ; loop through all words
;
pop cx
pop di
pop si
;
ret ; return from divsub
;
divsub endp
;
; LOCAL SUBROUTINE TO SHIFT QUOTIENT LEFT
;
quotshl proc near
;
push bx ; save registers
push cx
;
mov cx,isize ; count for single precision
;
quotshl1:
rcl word ptr [bx],1 ; shift word of quotient left once
inc bx ; point to next word
inc bx
loop quotshl1 ; loop through entire quotient
;
pop cx ; restore registers
pop bx
ret ; retirn from quotshl
;
quotshl endp
;
; ROUTINE TO DIVIDE MULTIDIGIT BINARY NUMBERS
;
mbindiv proc far
;
push si ; save registers
push di
push bx
push cx
push ax
;
; put single precision divisor into double precision location
push di ; save dividend pointer
lea di,tempdiv ; point to temporary divisor
mov cx,isize ; for a count of isize
cld ; forward direction
rep movsw ; make the transfer
;
; clear upper part of double precision location
mov ax,0 ; zero word
mov cx,isize ; for a count of isize
rep stosw ; clear the rest of the words
;
; restore dividend pointer and point to temp divisor
pop di ; restore dividend pointer
lea si,tempdiv ; point SI to temporary divisor
;
; initialize shift count
mov cx,1 ; initial count of one
;
; normalize divisor
mbindiv1:
test msbdiv,8000h ; test msb of divisor
jnz mbindiv2 ; exit if normalized
call divsal ; arithmetic shift if not
inc cx ; count the shift
jmp mbindiv1 ; keep on looping until normalized
;
; compare, subtract, shift loop
mbindiv2:
call divcmp ; compare divisor against dividend
ja mbindiv3 ; skip if too large
call divsub ; subtract if OK
stc ; new bit of quotient is 1
jmp mbindiv4 ; jump to end of loop
;
mbindiv3:
clc ; new bit of quotient is 0
;
mbindiv4:
call quotshl ; shift bit into the quotient
call divslr ; logical shift divisor right once
loop mbindiv2 ; loop for next digit
;
pop ax ; restore registers
pop cx
pop bx
pop di
pop si
;
mbindiv endp
;-------------------------mbindiv routine ends---------------------------

  3 Responses to “Category : Assembly Language Source Code
Archive   : ASM_SUBR.ZIP
Filename : MBINDIV

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/