📄 flda386.asm
字号:
push EDI ; save EDI
sub EDI,EDI ; indicate add
__add: add SI,1 ; add 1 to exponent
jc addnan1 ; quit if NaN
jo addnan1 ; ...
add ESI,0FFFFh ; readjust low exponent and inc high word
jc short addnan2 ; quit if NaN
jo short addnan2 ; ...
sub ESI,10000h ; readjust high exponent
xor ESI,EDI ; flip sign if subtract
pop EDI ; restore EDI
_guess ; guess: op1 is 0
or EAX,EAX ; - quit if op1 is not 0
_quif ne ; - ...
or EDX,EDX ; - quit if op1 is not 0
_quif ne ; - ...
_shl SI,1 ; - place sign in carry
_if e ; - if operand one is 0
shr ESI,16 ; - - get sign and exponent of op2
ret_op:
mov EAX,EBX ; - - return op2
mov EDX,ECX ; - - ...
_shl ESI,1 ; - - get rid of sign bit
or BX,SI ; - - or in exponent
or EBX,EDX ; - - check for 0
_if ne ; - - if not zero
shr ESI,1 ; - - - restore sign bit
_endif ; - - endif
ret ; - - return
_endif ; - endif
rcr SI,1 ; - put back the sign
_endguess ; endguess
_guess ; guess: op2 is 0
or ECX,ECX ; - quit if op2 is not 0
_quif ne ; - ...
or EBX,EBX ; - quit if op2 is not 0
_quif ne ; - ...
test ESI,7FFF0000h ; - quit if op2's exponent is not 0
_quif ne ; - ...
ret ; - return op1
_endguess ; endguess
push EBP ; save EBP
push EDI ; save EDI
xchg ECX,ESI ; get exponents and signs into ECX
mov EDI,ECX ; get exponent and sign of op1 into EDI
rol EDI,16 ; shift to top
sar EDI,16 ; shift exponent to bottom, duplicating sign
sar ECX,16 ; shift exponent to bottom, duplicating sign
and EDI,80007FFFh ; isolate signs and exponent
and ECX,80007FFFh ; ...
mov EBP,ECX ; assume op1 < op2
rol EDI,16 ; rotate signs to bottom
rol ECX,16 ; ...
add CX,DI ; calc sign of result
rol EDI,16 ; rotate signs to top
rol ECX,16 ; ...
sub CX,DI ; calculate difference in exponents
_if ne ; if different
_if b ; - if op2 < op1
mov EBP,EDI ; - - get larger exponent for result
neg CX ; - - negate the shift count
xchg EAX,EBX ; - - flip operands
xchg EDX,ESI ; - - . . .
_endif ; - endif
cmp CX,64 ; - if shift count too big
_if a ; - then, return operand 1
_shl EBP,1 ; - - get sign
rcr BP,1 ; - - merge with exponent
mov EAX,EBX ; - - get result
mov EDX,ESI ; - - ...
mov ESI,EBP ; - - ...
pop EDI ; - - restore EDI
pop EBP ; - - restore EBP
ret ; - - return
_endif ; - endif
_endif ; endif
mov CH,0 ; zero extend op2
or ECX,ECX ; get bit 0 of sign word - value is 0 if
; both operands have same sign, 1 if not
_if s ; if signs are different
mov CH,0FFh ; - set high part to ones
neg ESI ; - negate the fraction of op2
neg EBX ; - . . .
sbb ESI,0 ; - . . .
xor EBP,80000000h ; - flip sign
_endif ; endif
sub EDI,EDI ; get a zero for sticky bits
cmp CL,0 ; if shifting required
_if ne ; then
push EBX ; - save EBX
sub EBX,EBX ; - for zero fill
cmp CL,32 ; - if shift count >= 32
_if ae ; - then
or EAX,EAX ; - - check low order word for 1 bits
setne BL ; - - BL=1 if EAX non zero
mov EDI,EBX ; - - save sticky bits
sub EBX,EBX ; - - for zero fill
cmp CL,64 ; - - if shift count is 64 (19-nov-89)
_if e ; - - then
or EDI,EDX ; - - - get rest of sticky bits from high part
sub EDX,EDX ; - - - zero high part
_endif ; - - endif
mov EAX,EDX ; - - shift right 32
sub EDX,EDX ; - - zero high word
;;; sub CL,32 ; - - adjust shift count
_endif ; - endif
shrd EBX,EAX,CL ; - get the extra sticky bits
or EDI,EBX ; - save them
sub EBX,EBX ; - for zero fill
shrd EAX,EDX,CL ; - align the fractions
shrd EDX,EBX,CL ; - ...
pop EBX ; - restore EBX
_endif ; endif
add EAX,EBX ; add the fractions
adc EDX,ESI ; . . .
adc CH,0 ; . . .
_if s ; if answer is negative
cmp CL,64 ; - if shift count = 64
_if e ; - then
test EDI,7FFFFFFFh ; - - check the sticky bits
setne BL ; - - make single sticky bit
shr EBX,1 ; - - carry set if sticky=1
adc EAX,0 ; - - round up fraction if required
adc EDX,0 ; - - . . .
adc CH,0 ; - - . . .
_endif ; - endif
neg EDX ; - negate the fraction
neg EAX ; - ...
sbb EDX,0 ; - ...
mov CH,0 ; - zero top bits
xor EBP,80000000h ; - flip the sign
_endif ; endif
mov EBX,EAX ; get result
or BL,CH ; check for zero
or EBX,EDX ; if not zero
_if ne ; then
or BP,BP ; - if exponent is 0
je short denormal ; - denormal when exponent hits 0
cmp CH,0 ; - if top bits are 0
_if e ; - then
rol EDI,1 ; - - set carry from last sticky bit
ror EDI,1 ; - - ...
_loop ; - - loop (normalize)
dec BP ; - - - decrement exponent
je short denormal; - - denormal when exponent hits 0
_rcl EAX,1 ; - - - shift fraction left one bit
_rcl EDX,1 ; - - - ...
_until c ; - - until carry
_endif ; - endif
inc BP ; - increment exponent
cmp BP,7FFFh ; - quit if overflow
je add_oflow ; - . . .
stc ; - set carry
rcr EDX,1 ; - shift fraction right 1
rcr EAX,1 ; - ...
_if c ; - if guard bit is on
_shl EDI,1 ; - - get top sticky bit
_if e ; - - if no more sticky bits
ror EAX,1 ; - - - set carry with bottom bit of DX
rol EAX,1 ; - - - ...
_endif ; - - endif
adc EAX,0 ; - - round up fraction if required
adc EDX,0 ; - - . . .
_if c ; - - if we got a carry
rcr EDX,1 ; - - - shift fraction right 1
rcr EAX,1 ; - - - ...
inc BP ; - - - increment exponent
cmp BP,7FFFh ; - - - quit if overflow
je add_oflow ; - - - . . .
_endif ; - - endif
_endif ; - endif
_else ; else (answer is 0)
mov EBP,EBX ; - set exponent to 0
_endif ; endif
denormal: ; handle denormal
_addret:
_shl EBP,1 ; get sign
rcr BP,1 ; merge with exponent
mov ESI,EBP ; get exponent and sign into SI
pop EDI ; restore EDI
pop EBP ; restore EBP
ret ; return
add_oflow: ; handle overflow
mov BP,7FFFh ; get exponent for infinity
sub EAX,EAX ; set fraction
mov EDX,80000000h ; ...
jmp short _addret ; return
;; jmp F8OverFlow ; handle overflow
endproc ___LDA
ifdef _BUILDING_MATHLIB
endmod
endf equ end
else
endf equ <>
endif
endf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -