div386.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 308 行 · 第 1/2 页
ASM
308 行
;*****************************************************************************
;*
;* 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
.8087
modstart div386
xref __8087 ; indicate that NDP instructions are present
datasegment
extrn __real87 : byte ; 8087.asm
extrn __chipbug: byte
enddata
xref F8DivZero ; Fstatus
xref F8OverFlow ; Fstatus
xref F8UnderFlow ; Fstatus
xref __fdiv_m64
xdefp __FDD
; double __FDD( double , double )
sign equ -12
den equ sign-8
quot equ den-12
lo equ 0
hi equ 4
defpe __FDD
or EBX,EBX ; if low word of divisor is 0
_if e ; then
_shl ECX,1 ; - shift sign of divisor into carry
_if e ; - if divisor is zero
jmp F8DivZero ; - - handle divide by zero
_endif ; - endif
rcr ECX,1 ; - restore sign of divisor
_endif ; endif
or EAX,EAX ; check dividend for zero
_if e ; if so then
_shl EDX,1 ; - save sign of dividend
_if e ; - if dividend is 0
ret ; - - return
_endif ; - endif
rcr EDX,1 ; - restore sign of dividend
_endif ; endif
cmp byte ptr __real87,0 ; if no 80x87 is present
je short __FDDemu ; then emulate
__FDD87:
push EDX ; push operand 1
push EAX ; . . .
fld qword ptr [ESP] ; load operand 1
push ECX ; push operand 2
push EBX ; . . .
test byte ptr __chipbug,1 ; have we got a bad divider?
_if ne ; then
call __fdiv_m64 ; - call support rtn for divide
_else ; else
fdiv qword ptr [ESP] ; - divide operand 1 by operand 2
add ESP,8 ; - clean up stack
_endif ; endif
fstp qword ptr [ESP] ; store result
fwait ; wait
pop EAX ; load result into DX:AX
pop EDX ; . . .
cmp EDX,80000000H ; is it a negative zero?
_if e ; if it is then
sub EDX,EDX ; - make it positive 0.0
mov EAX,EDX ; - ...
_endif ; endif
ret ; return
__FDDemu:
push EBP ; save EBP
mov EBP,ESP ; get access to stack
push EDI ; save EDI
push ESI ; and ESI
mov EDI,EDX ; get high part of op1
mov ESI,ECX ; get high part of op2
sar EDI,20 ; shift exponent to bottom, duplicating sign
sar ECX,20 ; shift exponent to bottom, duplicating sign
and EDI,0800007FFh ; isolate signs and exponent
and ECX,0800007FFh ; ...
rol EDI,16 ; rotate signs to bottom
rol ECX,16 ; ...
add DI,CX ; calc sign of result
rol EDI,16 ; rotate signs to top
rol ECX,16 ; ...
and EDX,000FFFFFh ; isolate fraction
and ESI,000FFFFFh ; isolate fraction
or DI,DI ; if op1 is not a denormal
_if ne ; then
or EDX,00100000h ; - turn on implied 1 bit
_else ; else (denormal)
_loop ; - loop (normalize it)
_shl EAX,1 ; - - shift fraction left
_rcl EDX,1 ; - - . . .
dec DI ; - - decrement exponent
test EDX,00100000h ; - - until implied 1 bit is on
_until ne ; - until implied 1 bit is on
_endif ; endif
or CX,CX ; if op2 is not a denormal
_if ne ; then
or ESI,00100000h ; - turn on implied 1 bit
_else ; else (denormal)
_loop ; - loop (normalize it)
_shl EBX,1 ; - - shift fraction left
_rcl ESI,1 ; - - . . .
dec CX ; - - decrement exponent
test ESI,00100000h ; - - until implied 1 bit is on
_until ne ; - until implied 1 bit is on
_endif ; endif
sub DI,CX ; calculate exponent of result
add DI,03ffh ; add in removed bias
_guess ; guess: overflow
_quif s ; - quit if exponent is negative
cmp DI,07FFh ; - quit if not overflow
_quif b ; - . . .
mov EAX,ECX ; - put sign into EAX
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?