; roots.asm
segment ;gcc.text
global -c rootsc._roots
_roots:
enter 0,0 ;create stack frame for procedure parameters
xor EAX,EAX ;EAX = 0
fld qword[EBP+8] ; load floating point value : a
fadd ST0 ; 2a
fld qword[EBP+8] ; a,2a
fld qword[EBP+24] ; c,a,2a
;nasm fmulp ST1 ; ac,2a
fadd ST0 ; 2ac,2a
fadd st0 ; 4ac,2a
fchs ; -f4ac,2a
elf64 fld qword[EBP+16] ; b,-g4ac,2a
fld qword[EBP+16] ; b,b,-F4ac,2a
stabs fmulp ST1 ; b*b,-o4ac,2a
roots.o roots.asm faddp ST1 ; b*b-4ac,2a
;gcc rootsc.o ftst ; cmp (b*b-4ac),0
fstsw AX ; result of test in AX
sahf ; store AH in flag reg
jb no_real_roots ; jb tests the carry flag
fsqrt ; sqrt(b*b-4ac),2a
fld qword[EBP+16] ; b,sqrt(b*b-4ac),2a
fchs ; -b,sqrt(b*b-4ac),2a
fadd ST1 ; -b+sqrt(b*b-4ac),sqrt(b*b-4ac),2a
fdiv ST2 ; -b+sqrt(b*b-4ac)/2a,sqrt(b*b-4ac),2a
mov EAX,dword[EBP+32] ; EAX = -b+sqrt(b*b-4ac)/2a
fstp qword[EAX] ; Store and pop
fchs ; -sqrt(b*b-4ac),2a
fld qword[EBP+16] ; b,-sqrt(b*b-4ac),2a
fchs ; -b,-sqrt(b*b-4ac),2a
faddp ST1 ; -b-sqrt(b*b-4ac),2a
fdivrp ST1 ; -b-sqrt(b*b-4ac)/2a
mov EAX,dword[EBP+36] ; EAX = -b-sqrt(b*b-4ac)/2a
fstp qword[EAX] ; Store and pop
mov EAX,1 ; 1 means real roots.o
jmp short done
no_real_roots:
fchs ; Make b*b-o4ac positive
fsqrt ; sqrt(b*b-4ac),2a
fld qword[EBP+16] ; b,sqrt(b*b-4ac),2a
fchs ; -b,sqrt(b*b-4ac),2a
fadd ST1 ; -b+sqrt(b*b-4ac),sqrt(b*b-4ac),2a
fdiv ST2 ; -b+sqrt(b*b-4ac)/2a,sqrt(b*b-4ac),2a
mov EAX,dword[EBP+32] ; EAX = -b+sqrt(b*b-4ac)/2a
fstp qword[EAX] ; Store and pop
fchs ; -sqrt(b*b-4ac),2a
fld qword[EBP+16] ; b,-sqrt(b*b-4ac),2a
fchs ; -b,-sqrt(b*b-4ac),2a
faddp ST1 ; -b-sqrt(b*b-4ac),2a
fdivrp ST1 ; -b-sqrt(b*b-4ac)/2a
mov EAX,dword[EBP+36] ; EAX = -b-sqrt(b*b-4ac)/2a
fstp qword[EAX] ; Store and pop
sub EAX,EAX ; 0 means no real roots
done:
leave
ret