fdi4086.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 173 行
ASM
173 行
;*****************************************************************************
;*
;* Open Watcom Project
;*
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;* ========================================================================
;*
;* This file contains Original Code and/or Modifications of Original
;* Code as defined in and that are subject to the Sybase Open Watcom
;* Public License version 1.0 (the 'License'). You may not use this file
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;* provided with the Original Code and Modifications, and is also
;* available at www.sybase.com/developer/opensource.
;*
;* The Original Code and all software distributed under the License are
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;* NON-INFRINGEMENT. Please see the License for the specific language
;* governing rights and limitations under the License.
;*
;* ========================================================================
;*
;* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;* DESCRIBE IT HERE!
;*
;*****************************************************************************
;
include mdef.inc
include struct.inc
modstart fdi4086
xdefp __FDI4
xdefp __RDI4
xdefp __FDU4
xdefp __RDU4
;[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
;[]
;[] __FDU4 convert double float AX;BX;CX;DX into 32-bit integer DX:AX
;[] Input: AX BX CX DX - double precision floating point number
;[] Output: DX:AX - 32-bit integer
;[]
;[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
; convert floating double to 4-byte integer with rounding
defpe __RDU4
mov DX,0080h+0020h ; indicate we are rounding
jmp DtoI ; do it
defpe __RDI4
mov DX,0080h+001Fh ; indicate we are rounding
jmp DtoI ; do it
defpe __FDI4
mov DX,001Fh ; indicate we are truncating
jmp DtoI ; do it
; convert floating double to 4-byte integer with truncation
defpe __FDU4
mov DX,0020h ; indicate we are truncating
DtoI: _shl AX,1 ; get sign
rcr DH,1 ; DH <-- sign
shr DH,1 ; shift sign bit over 1
or DH,DL ; get rounding bit
shr AX,1 ; restore exponent to its place
; high bit of DH is rounding bit
; next bit is the sign bit
;<~> Shift real right four places so that exponent occupies an entire
;<~> word and the mantissa occupies the remaining words. We do not need
;<~> DX because we only need 32 sig digits
shr AX,1
rcr BX,1
rcr CX,1
shr AX,1
rcr BX,1
rcr CX,1
shr AX,1
rcr BX,1
rcr CX,1
shr AX,1
rcr BX,1
rcr CX,1
sub AX,03FEh ; remove bias from exponent
jl DIzero ; if |real| < .5 goto DIzero
cmp AX,20h ; if exponent > 32
jg DIo_f ; goto DIo_flow
and DL,3Fh ; isolate # of significant bits
cmp AL,DL ; quit if number too big
jg DIo_f ; goto DIo_flow
stc ; set carry and
rcr BX,1 ; restore implied 1/2 bit
rcr CX,1
rcr AH,1 ; save rounding bit
mov DL,32 ; # of bits to shift right = 32 - AL
sub DL,AL ; ...
mov AL,DL ; ...
_guess ; guess: exponent >= 16
cmp AL,16 ; - quit if < 16
_quif l ; - ...
mov AH,CH ; - save rounding bit
mov CX,BX ; - shift right 16 bits
sub BX,BX ; - zero high word
sub AL,16 ; - adjust exponent by 16
_endguess ; endguess
_guess ; guess: exponent >= 8
cmp AL,8 ; - quit if < 8
_quif l ; - . . .
mov AH,CL ; - save rounding bit
mov CL,CH ; - shift right 8 bits
mov CH,BL ; - . . .
mov BL,BH ; - . . .
mov BH,0 ; - zero high byte
sub AL,8 ; - adjust exponent by 8
_endguess ; endguess
cmp AL,0 ; if there are bits to shift
_if ne ; then
_loop ; - loop
shr BX,1 ; - - shift mantissa into integer
rcr CX,1 ; - - . . .
rcr AH,1 ; - - save rounding bit
dec AL ; - - dec AL
_quif e ; - - quif AL = 0
shr BX,1 ; - - shift mantissa into integer
rcr CX,1 ; - - . . .
rcr AH,1 ; - - save rounding bit
dec AL ; - - decrement exponent
_until e ; - until done
_endif ; endif
and AH,DH ; trunc or rnd as determined by high bit of DH
_shl DH,1 ; get extra significant bit from mantissa
adc CX,0 ; add it to the integer to round it up
adc BX,0 ; . . .
_shl DH,1 ; get sign
_if c ; if negative
not BX ; - negate integer
neg CX ; - . . .
sbb BX,-1 ; - . . .
_endif ; endif
mov AX,CX ; put result in correct registers
mov DX,BX ; . . .
ret ; return
DIo_f:
mov DX,8000h ; set answer to largest negative number
sub AX,AX ; . . .
ret ; return
; jmp I4OverFlow ; report overflow
DIzero: sub AX,AX ; set result to zero
sub DX,DX ; . . .
ret
endproc __FDU4
endproc __FDI4
endproc __RDI4
endproc __RDU4
endmod
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?