fsmath.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 344 行 · 第 1/2 页
ASM
344 行
ror EAX,8 ; rotate into position
ror CL,1 ; get sign bit
rcr EAX,1 ; shift it into result
pop EBX ; restore EBX
pop ECX ; restore ECX
ret ; return
add_uflow: ; handle underflow
pop EBX ; restore EBX
pop ECX ; restore ECX
jmp F4UnderFlow ; goto underflow routine
add_oflow: ; handle overflow
pop EBX ; restore EBX
pop ECX ; restore ECX
jmp F4OverFlow ; handle overflow
endproc __FSA
endproc __FSS
;=====================================================================
defp __FSM
;<> multiplies X by Y and places result in C.
;<> X2 and X1 represent the high and low words of X. Similarly for Y and C
;<> Special care is taken to use only six registers, so the code is a bit
;<> obscure
_guess ; guess: answer not 0
or EAX,EAX ; - see if first arg is zero
_quif e ; - quit if op1 is 0
or EDX,EDX ; - quit if op2 is 0
_quif e ; - . . .
jne __FSMemu ; - perform multiplication
_endguess ; endguess
sub EAX,EAX ; set answer to 0
ret ; return
__FSMemu:
push ECX ; save ECX
_shl EAX,1 ; get sign of op1
_rcl ECX,1 ; save it
_shl EDX,1 ; get sign of op2
adc ECX,0 ; calc sign of result
ror ECX,1 ; move to the top
rol EAX,8 ; move exponent of op1 into AL
rol EDX,8 ; move exponent of op2 into DL
sub AL,7Fh ; remove bias from exponents
sub DL,7Fh ; . . .
add DL,AL ; add exponents
_if o ; if over or underflow
js short mul_oflow ; - report overflow if signed
jmp short mul_uflow ; - handle underflow
_endif ; endif
cmp DL,81h ; check for underflow
jle short mul_uflow ; quit if underflow
add DL,7fh+1 ; bias exponent
mov CL,DL ; save exponent
mov AL,0 ; zero rest of fraction
mov DL,0 ; ...
stc ; turn on implied 1 bit in fraction
rcr EAX,1 ; ...
stc ; turn on implied 1 bit in fraction
rcr EDX,1 ; ...
mul EDX ; calc fraction
or EDX,EDX ; check top bit
_if ns ; if not set
_shl EDX,1 ; - move left 1
dec CL ; - decrement exponent
_endif ; endif
sar EDX,8 ; place fraction in correct location
adc EDX,0 ; round up
adc CL,0 ; increment exponent if necessary
jz short mul_oflow ; report overflow if required
shl EDX,9 ; get rid of implied 1 bit
mov DL,CL ; get exponent
ror EDX,8 ; rotate into position except for sign
_shl ECX,1 ; get sign
rcr EDX,1 ; place sign in result
mov EAX,EDX ; place in correct register
pop ECX ; restore ECX
ret ; return
mul_uflow: ; underflow
pop ECX ; restore ECX
jmp F4UnderFlow ; . . .
mul_oflow: ; overflow
mov EAX,ECX ; get sign
pop ECX ; restore ECX
jmp F4OverFlow ; report overflow
endproc __FSM
;====================================================================
defp __FSD
_shl EDX,1 ; shift sign of divisor into carry
_if e ; if divisor is zero
jmp F4DivZero ; - handle divide by zero
_endif ; endif
push ECX ; save ECX
_rcl ECX,1 ; save sign in ECX
_shl EAX,1 ; shift sign of dividend into carry
_if e ; if dividend is 0, then
pop ECX ; - restore ECX
ret ; - return
_endif ; endif
adc ECX,0 ; now calculate save sign of result in ECX
ror ECX,1 ; rotate sign to top
rol EAX,8 ; get exponent into AL
rol EDX,8 ; get exponent into DL
sub AL,7Fh ; calculate exponent of result
sub DL,7Fh ; . . .
sub AL,DL ; . . .
_if o ; if over or underflow
jns short div_uflow ; - handle underflow
_shl ECX,1 ; - get sign of infinity
rcr EAX,1 ; - . . .
jmp short div_oflow ; - handle overflow
_endif ; endif
cmp AL,81h ; check for underflow
jle short div_uflow ; . . .
add AL,7Fh ; restore bias to exponent
mov CH,AL ; save calculated exponent
mov AL,0 ; zero bottom of fraction
mov DL,0 ; ...
stc ; rotate implied '1'bit back into divisor
rcr EDX,1 ; . . .
stc ; rotate implied '1' bit into dividend
rcr EAX,1 ; . . .
push ECX ; save sign and exponent
mov ECX,EDX ; save divisor
mov EDX,EAX ; place dividend into EDX
sub EAX,EAX ; set rest to 0
shr EDX,1 ; so we don't get a divide overflow trap
div ECX ; do the divide
pop ECX ; restore sign and exponent
or EAX,EAX ; check top bit
_if ns ; if not set
_shl EAX,1 ; - move left 1
dec CH ; - decrement exponent
_endif ; endif
sar EAX,8 ; place fraction in correct location
adc EAX,0 ; round up
_guess ; guess have to inc exponent
_quif nc ; - quit if no carry
inc CH ; - increment exponent
_quif nz ; - quit if no overflow
mov EAX,ECX ; - get sign of infinity
jmp short div_oflow ; - handle overflow
_endguess ; endguess
shl EAX,9 ; get rid of implied 1 bit
mov AL,CH ; get exponent
ror EAX,8 ; rotate into position except for sign
_shl ECX,1 ; get sign
rcr EAX,1 ; place sign in result
pop ECX ; restore ECX
ret ; return to caller
div_uflow: ; handle underflow
pop ECX ; restore ECX
jmp F4UnderFlow ; handle underflow
div_oflow: ; handle overflow
pop ECX ; restore ECX
jmp F4OverFlow ; handle overflow
endproc __FSD
endmod grmath
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?