fldc086.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 145 行
ASM
145 行
ifdef _BUILDING_MATHLIB
include mdef.inc
include struct.inc
include xception.inc
modstart fldc086, word
endif
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
;<>
;<> __FLDC - long double comparison
;<> input: AX - pointer to operand 1
;<> DX - pointer to operand 2
;<> if op1 > op2, 1 is returned in AX
;<> if op1 < op2, -1 is returned in AX
;<> if op1 = op2, 0 is returned in AX
;<> if either opnd is NaN, then 2 is returned in AX
;<>
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
xdefp __FLDC
defp __FLDC
ifdef _BUILDING_MATHLIB
push DS ; save DS
push SS ; fpc code assumes parms are relative to SS
pop DS ; ...
endif
push DI ; save DI
push SI ; save SI
mov SI,AX ; point to op1
mov DI,DX ; point to op2
_guess ; guess: op1 is not a NaN
mov AX,8[SI] ; - get sign and exponent of op1
or AH,80H ; - turn on sign bit (all 1's if a NaN)
inc AX ; - will be 0 if a NaN
_quif ne ; - quit if not a NaN
mov AX,4[SI] ; - or in rest of fraction
or AX,2[SI] ; - ...
or AX,[SI] ; - ...
jne cmpNaN ; - non-zero fraction means its a NaN
mov AX,6[SI] ; - get high order word of fraction
cmp AX,8000h ; - check for infinity
jne cmpNaN ; - 8000h => Inf, otherwise NaN
_endguess ; endguess
_guess ; guess: op2 is not a NaN
mov AX,8[DI] ; - get sign and exponent of op2
or AH,80H ; - turn on sign bit (all 1's if a NaN)
inc AX ; - will be 0 if a NaN
_quif ne ; - quit if not a NaN
mov AX,4[DI] ; - or in rest of fraction
or AX,2[DI] ; - ...
or AX,[DI] ; - ...
jne cmpNaN ; - non-zero fraction means its a NaN
mov AX,6[DI] ; - get high order word of fraction
cmp AX,8000h ; - check for infinity
jne cmpNaN ; - 8000h => Inf, otherwise NaN
_endguess ; endguess
mov DX,8[SI] ; get sign and exponent of op1
mov AX,8[DI] ; get sign and exponent of op2
xor AX,DX ; see about signs of the operands
mov AX,0 ; clear result
js short chkfor0 ; quif arg1 & arg2 have diff signs
_guess ; guess
cmp DX,8[DI] ; - compare exponents
_quif ne ; - quif not equal
mov AX,6[SI] ; - get high part of fraction
cmp AX,6[DI] ; - compare them
_quif ne ; - quif not equal
mov AX,4[SI] ; - get next part of fraction
cmp AX,4[DI] ; - compare them
_quif ne ; - quif not equal
mov AX,2[SI] ; - get next part of fraction
cmp AX,2[DI] ; - compare them
_quif ne ; - quif not equal
mov AX,[SI] ; - get low part of fraction
cmp AX,[DI] ; - compare them
_endguess ; endguess
mov AX,0 ; clear result
_if ne ; if arg1 <> arg2
rcr AX,1 ; - save carry in AX
xor DX,AX ; - sign of DX is sign of result
cmpdone: _shl DX,1 ; - get sign of result into carry
sbb AX,0 ; - AX gets sign of result
_shl AX,1 ; - double AX
inc AX ; - make AX -1 or 1
_endif ; endif
pop SI ; restore SI
pop DI ; restore DI
ifdef _BUILDING_MATHLIB
pop DS ; restore DS
endif
ret ; return to caller
cmpNaN: mov AX,2 ; indicate NaN
pop SI ; restore SI
pop DI ; restore DI
ifdef _BUILDING_MATHLIB
pop DS ; restore DS
endif
ret ; return to caller
chkfor0:or AX,[SI] ; see if both operands are 0
or AX,[DI] ; ...
or AX,2[SI] ; ...
or AX,2[DI] ; ...
or AX,4[SI] ; ...
or AX,4[DI] ; ...
or AX,6[SI] ; ...
or AX,6[DI] ; ...
and DX,7FFFh ; get rid of sign from op1
or AX,DX ; check for zero
mov DX,8[DI] ; get exponent of op2
and DX,7FFFh ; get rid of sign from op2
or AX,DX ; check for zero
mov DX,8[SI] ; get sign of op1
mov AX,0 ;
jne cmpdone ; if not zero
pop SI ; restore SI
pop DI ; restore DI
ifdef _BUILDING_MATHLIB
pop DS ; restore DS
endif
ret ; return to caller
endproc __FLDC
ifdef _BUILDING_MATHLIB
endmod
endf equ end
else
endf equ <>
endif
endf
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?