home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
math
/
float.asm
< prev
next >
Wrap
Assembly Source File
|
1986-01-17
|
10KB
|
181 lines
;*******************************************************************
; FLOATING POINT
; ADDITION AND SUBTRACTION
; ROUTINE
;*******************************************************************
FLOAT_A PROC NEAR
;entry point for subtraction
SUB_F: MOV BX,0080H ;set mask to reverse sign of operand2
JMP SHORT F1 ;and go to main routine
;
;entry point for addition
ADD_F: SUB BX,BX ;clear mask register BX
;
;get operand1 from address in DI
F1: PUSH SI ;save index registers
PUSH DI ;
MOV DX,[DI]+2 ;exponent goes in DH--mantissa in DL
MOV AX,[DI] ;and AX
;get operand2 from address in SI
XOR BX,[SI]+2 ;exponent goes in BH--mantissa in BL
MOV CX,[SI] ;and CX
;***************************************************
; Floating point addition routine begins here
; operands are in the following format:
; DH DL bit 7 DL AX
; Operand1 exponent sign mantissa
;
; BH BL bit 7 BL CX
; Operand2 exponent sign mantissa
;***************************************************
;save signs
MOV SI,10000000B ;put mask for sign bit is SI
MOV DI,SI ;and in DI
AND SI,DX ;put sign of operand1 in SI bit 7
AND DI,BX ;put sign of operand2 in DI bit 7
CMP SI,DI ;
JE A1 ;if signs are unequal
ADD DI,8000H ;set bit 15 to 1. Bit 15 is
ADD SI,8000H ;addition/subtraction flag
A1: OR DL,10000000B ;restore leading ones
OR BL,10000000B ;
;put smaller operand in DX:AX
CMP DX,BX ;compare first word
JA A2 ;exchange if DX:AX is larger
JB A3 ;
CMP AX,CX ;equal first words; compare second
JA A2 ;
JB A3 ;
;operands are equal
OR DI,DI ;if signs are unequal
JNS A3 ;
SUB DX,DX ;set result in DX:AX to zero
MOV AX,DX ;
JMP EXIT ;and return
A2: XCHG DX,BX ;exchange operands
XCHG AX,CX ;
MOV DI,SI ;put sign of larger in DI
A3: MOV SI,CX ;larger operand is now in BX:SI
;compute exponent difference
MOV CL,BH ;put larger exponent in CL
SUB CL,DH ;and subtract the smaller exponent
;CL is COUNT of bits to shift DX:AX
CMP CL,24 ;if COUNT > 24, smaller operand is
JLE A4 ;effectively 0, so
MOV DX,BX ;put larger operand(result) in DX:AX
MOV AX,SI ;
JMP FINISH ;and finish
;ALIGN fractions (shift smaller right)
A4: SUB DH,DH ;clear DH
MOV CH,DH ;clear CH
A5: CMP CL,8 ;
JL A6 ;if COUNT >= 8
;shift right in byte increments
OR CH,DH ;put trailing bits in CH
MOV DH,AL ;move leading bits in AL (and any
;others that happen to be set) to DH
MOV AL,AH ;shift upper bytes right
MOV AH,DL ;
SUB DL,DL ;set leading byte to zero
SUB CL,8 ;decrement COUNT
JMP SHORT A5 ;if COUNT >= 8, repeat
A6: OR CH,CH ;if any bits set in CH
JZ A7 ;
OR CH,80H ;set sticky bit
A7: OR CL,CL ;
JZ A9 ;if COUNT > 0
;shift right COUNT bits
A8: SHR DL,1 ;rotate mantissa in DL:AX right
RCR AX,1 ;
RCR DH,1 ;rotate round bits in DH:CH right
RCR CH,1 ;
DEC CL ;decrement COUNT
JNZ A8 ;repeat if COUNT in CL not zero
MOV CL,3FH ;put mask in lower 6 bits of CL
AND CL,DH ;pick up rounding bits from DH
AND DH,0C0H ;zero out all but two guard bits in DH
;operands are now aligned
A9: OR DI,DI ;if signs were the same,i.e., sign
JS A10 ;bit = 0, then
ADD AX,SI ;ADD the two operands
ADC DL,BL ;
JNC R0 ;if there was a carry, fraction is
;greater than 0, so normalize
INC BH ;increment exponent
JZ OVER_F ;jump if exponent overflow
RCR DL,1 ;shift fraction right one bit
RCR AX,1 ;
RCR DH,1 ;
JMP SHORT R0 ;
;SUBTRACT the two operands
A10: XCHG SI,AX ;put larger operand in DL:AX
XCHG DL,BL ;
NEG DH ;subtract DH (guard bits)
SBB AX,SI ;subtract significant portions
SBB DL,BL ;
JS R0 ;if DL bit 7 is 1, round
;NORMALIZE
A11: DEC BH ;decrement exponent
JZ UNDER_F ;jump if exponent underflow
SHL DH,1 ;shift mantissa left
RCL AX,1 ;
RCL DL,1 ;
OR DL,DL ;
JNS A11 ;repeat if still not normalized
RO: OR CH,CL ;set sticky bit before rounding
JZ R1 ;if any trailing bits in CX
OR DH,01000000B ;set sticky bit in DH
;ROUND normalized result
R1: OR DH,DH ;if guard bit in DH is 0,
JNS FINISH ;rounding is not necessary
;guard bit is on
TEST AL,1 ;if fraction is odd, then
JNZ R2 ;round it
AND DH,7FH ;check trailing bits in DH and CX
JZ FINISH ;if all zeros, rounding not needed
R2: ADD AX,1 ;round by adding one
ADC DL,0 ;
JNC FINISH ;rounding may denormalize mantissa
RCR DL,1 ;normalize by shifting right one
RCR AX,1 ;
INC BH ;increment exponent
JZ OVER_F ;jump if exponent overflow
FINISH: AND DL,7FH ;set sign bit to 0
OR DX,DI ;restore sign from bit 7 of DI
MOV DH,BH ;put exponent in DH
SUB BX,BX ;set status=0 -- OK
EXIT: POP DI ;restore index registers
POP SI ;
RET
OVER_F: MOV DX,0FF7FH ;here for overflow--set result in DX:AX
MOV AX,0FFFFH ;to maximum possible value with positive
OR DX,DI ;sign. Restore actual result sign.
MOV BX,1 ;set status=1 -- overflow
JMP SHORT EXIT ;
UNDER_F: SUB DX,DX ;set result in DX:AX to zero
MOV AX,DX ;
MOV BX,-1 ;set status=-1 -- underflow
JMP SHORT EXIT ;
FLOAT_A ENDP