Category : Assembly Language Source Code
Archive   : MATHASM.ZIP
Filename : DIV_F.ASM

 
Output of file : DIV_F.ASM contained in archive : MATHASM.ZIP
;*************************************************************
; FLOATING POINT
; DIVISION ROUTINE
;*************************************************************
DIV_F PROC NEAR
PUSH SI ;save index registers
PUSH DI
; divide by zero?
MOV DX,[SI] ;get op2 (divisor) in CX:DX
MOV CX,[SI]+2
MOV BX,10 ;set error flag
MOV AX,DX ;is op2 zero?
OR AX,CX
JNZ D1 ;if zero, quit with BX=10
JMP EXIT
; compute result sign
D1: MOV AL,CL ;OP1 high byte in AL
XOR AL,[DI]+2 ;XOR with OP2 high byte
AND AX,0080H ;isolate sign bit
PUSH AX ;save it
; compute exponent
SUB AX,AX
MOV BX,AX
MOV AL,CH ;E2 in AX
MOV BL,[DI]+3 ;E1 in BX
SUB AX,128 ;remove bias
SUB BX,AX ;E1-E2
INC BX ;add 1 since shift right later
;
CMP BX,255 ;overflow if
JLE D3 ;E>255
JMP D13
;
D3: CMP BX,0 ;underflow if
JGE D5 ;E<0
JMP D14
; compute 1-(OP2LO/OP2HI)/2^16
D5: PUSH BX ;save E in BL
SUB AX,AX
MOV BH,CL ;OP2HI in BX
MOV BL,DH
OR BH,10000000B ;restore leading 1
MOV DH,DL ;OP2LO in DX
MOV DL,AL
OR DX,DX ;if OP2LO is zero
JNZ D6
XCHG BX,AX ;put OP2HI in AX
MOV SI,BX ;set result in BX:SI to zero
JMP SHORT D8 ;and skip this step
; compute OP2LO/OP2HI first
D6: SUB CX,CX
CMP DX,BX ;if OP2LO>=OP2HI, quotient>=1
JB D7
SUB DX,BX ;subtract OP2HI to prevent overflow
MOV CX,1 ;save quotient 1 or 0 in CX
;
D7: DIV BX ;OP2LO/OP2HI now in CX:AX
;
PUSH CX ;save OP2LO/OP2HI
PUSH AX
SUB AX,AX ;divide remainder in DX:AX
DIV BX
POP DX
POP CX ;OP2LO/OP2HI in CX:DX:AX
; subtract it from 1
PUSH DI ;save DI & OP2HI
PUSH BX
SUB DI,DI ;clear registers
MOV SI,DI
MOV BX,DI
SUB DI,AX
SBB SI,DX
SBB BX,CX
POP AX ;retrieve OP2HI & DI
POP DI
; compute OP1/OP2HI
D8: PUSH BX ;save 1-OP1LO/OP2HI
PUSH SI
MOV BX,AX ;OP2HI in BX
SUB AX,AX ;clear AX & SI
MOV SI,AX
MOV DX,[DI]+1 ;OP1 in DX:AX
OR DH,10000000B ;restore leading 1
MOV AH,[DI]
;
CMP DX,BX ;if OP1>=OP2HI
JB D9
SUB DX,BX ;subtract OP2HI to prevent overflow
INC SI ;and save quotient of one in SI
;
D9: DIV BX ;divide OP1/OP2HI
MOV CX,AX ;save quotient in CX
SUB AX,AX
DIV BX ;divide remainder in DX
MOV DX,CX ;OP1/OP2HI now in SI:DX:AX
SHR SI,1 ;shift it right
RCR DX,1
RCR AX,1 ;now in DX:AX
; compute (OP1/OP2HI)*(OP2LO/OP2HI)/2^16
POP BX ;1-OP2LO/OP2H9)/2^16 in CX:BX
POP CX
MOV SI,BX ;if OP2LP/OP2HI was zero
OR SI,CX ;product is OP1/OP2HI
JZ D10 ;so no need to multiply
CALL MUL32 ;do the multiplication
; normalize
D10: POP BX ;get exponent in BX
D11: OR DX,DX
JS D12 ;if sign bit off
SHL CX,1 ;shift it left
RCL AX,1
RCL DX,1
DEC BX ;decrement exponent
JMP D11 ;see if normalized
; reformat for output
D12: MOV BH,BL ;exponent in BH
XCHG AH,AL ;move trailing bits up to DH
XCHG DL,AH ;4 byte mantissa in DL:AX:DH
XCHG DH,DL
SUB CX,CX
POP DI ;result sign in DI
JMP R0 ;ROUND in addition routine
;
D13: POP DI ;get sign in DI
JMP OVER_F
D14: POP AX ;remove sign from stack
JMP UNDER_F
DIV_F ENDP

  3 Responses to “Category : Assembly Language Source Code
Archive   : MATHASM.ZIP
Filename : DIV_F.ASM

  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/