trig387.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 532 行 · 第 1/2 页
ASM
532 行
shl BL,1 ; double it for index
mov BH,0 ; zero high byte
lea BX,octtab[BX] ; point to table entry
mov AX,cs:[BX] ; get address of routine from table
pop BX ; clean up the stack
pop BX ; restore BX
pop BP ; restore BP
jmp AX ; jump to appropriate routine
endif ; __386__
; at this point the 8087 stack looks like this:
;
; st(0) = R
; st(1) = X
; st(2) = Y
; st(3) = fac2
;
; sin(theta) = Y/R
; cos(theta) = X/R
oct4: ; octant 4
oct7: ; octant 7
fchs ; change sign of R, to get -sin(theta)
oct0: ; octant 0
oct3: ; octant 3
fstp st(1) ; copy R up over X
fdivp st(1),st(0) ; sin(theta) = Y/R
ret ; return
oct5: ; octant 5
oct6: ; octant 6
fchs ; change sign of R, to get -cos(theta)
oct1: ; octant 1
oct2: ; octant 2
fdivp st(1),st(0) ; cos(theta) = X/R
fstp st(1) ; copy answer up over Y
ret ; return
endif ; __FPI87__
endproc IF@SIN
endproc IF@DSIN
chk_C2 proc near
push _BP ; save BP
mov _BP,_SP ; get access to stack
push _AX ; allocate stack space
fstsw word ptr -2[_BP]; get status word
fwait
mov AH,-1[_BP] ; get flags
or AH,1 ; force carry bit on (assume arg in range)
sahf ; copy to flags
_if p ; if argument not in range
fld tbyte ptr TwoPi ; - load 2*pi
fxch st(1) ; - get them in correct position
_loop ; - loop (reduce argument to range)
fprem ; - - reduce the argument
fstsw word ptr -2[_BP]; - - get status
fwait
mov AH,-1[_BP] ; - - ...
sahf ; - - ...
_until np ; - until argument in range
fstp st(1) ; - copy up the new argument
clc ; - indicate must retry instruction
_endif ; endif
pop _AX ; clean up stack
pop _BP ; restore BP
ret ; return
endproc chk_C2
defp cos
ifdef __386__
fld qword ptr 4[ESP]; load argument
call IF@DCOS ; calculate cos(x)
loadres ; load result
else
push BP ; save BP
mov BP,SP ; get access to parms
fld qword ptr argx[BP]; load argument x
lcall IF@DCOS ; calculate cos(x)
pop BP ; restore BP
endif ; __386__
ret_pop 8 ; return
endproc cos
defp sin
ifdef __386__
fld qword ptr 4[ESP]; load argument
call IF@DSIN ; calculate sin(x)
loadres ; load result
else
push BP ; save BP
mov BP,SP ; get access to parms
fld qword ptr argx[BP]; load argument x
lcall IF@DSIN ; calculate sin(x)
pop BP ; restore BP
endif ; __386__
ret_pop 8 ; return
endproc sin
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
;<> <>
;<> TAN function for 8087 <>
;<> <>
;<> tan387 - compute tan of st(0) <>
;<> <>
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
public IF@TAN
public IF@DTAN
defp IF@DTAN
defp IF@TAN
ifdef __FPI87__
do_fptan ; calculate tan
fstp st(0) ; get rid of the 1.0 pushed by fptan
ret ; return
else
chk387 ; check for 387
_if e ; if 387
do_fptan ; - calculate tan
fstp st(0) ; - get rid of the 1.0 pushed by fptan
ret ; - return
_endif ; endif
ifdef __386__
push EBX ; save EBX
fldpi ; load pi
sub EBX,EBX ; init 'invert'(BH) flag and 'negate'(BL) flag
fxch st(1) ; get argument
ftst ; get sign of argument
fstsw AX ; . . .
sahf ; get flags ZF = C3, CF = C0
_if b ; if argument is negative
fchs ; - make argument positive
not BL ; - indicate result to be negated
_endif ; endif
_loop ; loop (reduce argument to mod pi)
fprem ; - calculate partial remainder
fstsw AX ; - store status word
sahf ; - ... PF = C2
_until np ; until C2 is clear
fld tbyte ptr piby2 ; load pi/2
fstp st(2) ; stack is r, pi/2
fcom ; compare r to pi/2
fstsw AX ; . . .
sahf ; get flags ZF = C3, CF = C0
_if a ; if r > pi/2
fsub st,st(1) ; - tan(r) = -1/tan(r - pi/2)
not EBX ; - set the 'invert' flag, complement 'negate'
_endif ; endif
fld tbyte ptr piby4 ; load pi/4
fcomp ; compare pi/4 to r and pop
fstsw AX ; . . .
sahf ; get flags ZF = C3, CF = C0
_if b ; if r > pi/4
fsubr st,st(1) ; - tan(r) = 1/tan(pi/2 - r)
not BH ; - complement the 'invert' flag
_endif ; endif
fstp st(1) ; copy r up over pi/2
fptan ; st(1)/st(0) = tangent, st(0) = X, st(1) = Y
cmp BH,0 ; if result is inverted
_if ne ; then
fdivr ; - 1/tangent = st(0)/st(1)
_else ; else
fdiv ; - tangent = st(1)/st(0)
_endif ; endif
cmp BL,0 ; if result to be negated
_if ne ; then
fchs ; - negate result
_endif ; endif
pop EBX ; restore registers
else
push BP ; save BP
mov BP,SP ; get access to stack
push AX ; allocate auto
push AX ; save registers
push BX ; . . .
push CX ; . . .
push DX ; . . .
fldpi ; load pi
sub BX,BX ; init 'invert' flag
sub CX,CX ; init 'negate' flag
fxch st(1) ; get argument
ftst ; get sign of argument
fstsw word ptr -2[BP] ; . . .
fwait ; . . .
mov AX,-2[BP] ; . . .
sahf ; get flags ZF = C3, CF = C0
_if b ; if argument is negative
fchs ; - make argument positive
not CX ; - indicate result to be negated
_endif ; endif
_loop ; loop (reduce argument to mod pi)
fprem ; - calculate partial remainder
fstsw word ptr -2[BP] ; - store status word
fwait ; - wait for store to complete
mov AX,-2[BP] ; - get status
sahf ; - ... PF = C2
_until np ; until C2 is clear
fld tbyte ptr piby2 ; load pi/2
fstp st(2) ; stack is r, pi/2
fcom ; compare r to pi/2
fstsw word ptr -2[BP] ; . . .
fwait ; . . .
mov AX,-2[BP] ; . . .
sahf ; get flags ZF = C3, CF = C0
_if a ; if r > pi/2
fsub st,st(1) ; - tan(r) = -1/tan(r - pi/2)
not BX ; - set the 'invert' flag
not CX ; - complement the 'negate' flag
_endif ; endif
fld tbyte ptr piby4 ; load pi/4
fcomp ; compare pi/4 to r and pop
fstsw word ptr -2[BP] ; . . .
fwait ; . . .
mov AX,-2[BP] ; . . .
sahf ; get flags ZF = C3, CF = C0
_if b ; if r > pi/4
fsubr st,st(1) ; - tan(r) = 1/tan(pi/2 - r)
not BX ; - complement the 'invert' flag
_endif ; endif
fstp st(1) ; copy r up over pi/2
fptan ; st(1)/st(0) = tangent, st(0) = X, st(1) = Y
or BX,BX ; if result is inverted
_if ne ; then
fdivr ; - 1/tangent = st(0)/st(1)
_else ; else
fdiv ; - tangent = st(1)/st(0)
_endif ; endif
or CX,CX ; if result to be negated
_if ne ; then
fchs ; - negate result
_endif ; endif
pop DX ; restore registers
pop CX ; . . .
pop BX ; . . .
pop AX ; . . .
pop BP ; clean off auto
pop BP ; restore BP
endif ; __386__
ret ; return
endif ; __FPI87__
endproc IF@TAN
endproc IF@DTAN
defp tan
ifdef __386__
fld qword ptr 4[ESP]; load argument
call IF@DTAN ; calc the tan
loadres ; load result
else
push BP ; save BP
mov BP,SP ; get access to parms
fld qword ptr argx[BP]; load argument x
lcall IF@DTAN ; calculate tan(x)
pop BP ; restore BP
endif ; __386__
ret_pop 8 ; return
endproc tan
endmod
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?