We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Linux nasm square root algorithm poblem

SaumZ
SaumZ asked
on
Medium Priority
601 Views
Last Modified: 2008-02-01
I am programming with the FPU under linux and the NASM assembler and linking using gcc

Here is the algorithm I am implementing:

take in x from the keyboard

 Initialize x_new = x
 do
     x_old = x_new;
     x_new = (x_old + x / x_old) / 2;
   while |x_old - x_new|/x_new > e


I am having the problem with my compare and my conditional jump.
I have tested the values of the algorthm throughout and the values are correct to what I worked out on paper.
;------------------------------------------------------------------------------
extern  printf
extern  scanf
 
global main
 
segment .data
prompt: db "Please enter a number: ",0
format: db "%lf", 0
output: db "%lf",10, 0
 
epsilon dq  0.0001
x2:     dq  2.0
 
segment .bss
x:      resq 1
x_new:  resq 1
x_old:   resq 1
x_temp:  resq 1
segment .text
main:
        pusha
 
        push prompt
        call printf
        add esp, 4
 
        push x
        push format
        call scanf
        add esp, 8
 
        fld qword [x]               ;fstack: x
        fstp qword [x_new]      ;fstack:
                                          ;x_new = x
.L1:    finit
        fld qword [x_new]       ;fstack: x_new
        fstp qword [x_old]       ;fstack:
                                         ;x_old = x_new
        finit                            ;clear the stack
                                         ;now lets make x_new = (x_old + (x/x_old))/2
        fld qword [x]              ;fstack: x
        fdivr qword [x_old]     ;fstack: x/x_old
        fadd qword [x_old]      ;fstack:(x_old + (x/x_old))
        fdiv qword [x2]           ;fstack:(x_old + (x/x_old))/2
        fstp qword [x_new]      ;fstack:
 
        finit                            ;clear the stack
                                          ;now lets make |x_old - x_new|/x_new
        fld qword [x_old]         ;fstack: x_old
        fsub qword [x_new]     ;fstack: x_old - x_new
        fabs                            ;fstack: |x_old - x_new|
        fdiv qword [x_new]      ;fstack: |x_old - x_new|/x_new
 
        fld qword [epsilon]     ;fstack: epsilon, |x_old - x_new|/x_new
 ;PROBLEM IS WITH THE COMPARE AND JUMP HERE
        fcomi st1                       ;compare ST0 with ST1
        jl .L1
 
        finit
        push dword [x_new + 4]   ;outputting x_new after loop
        push dword [x_new]
        push output
        call printf
        add esp, 12

        popa
        mov eax, 0
        ret
Comment
Watch Question

Commented:
I believe you have a reason for not using FSQRT instead.

Well, by definition "jl" jumps if "SF <> OF".
However, fcomi sets the following flags: ZF, PF, CF.
So change jl to jc. Voila.

Author

Commented:
I tried the jump with jc, and my code is still only doing one iteration. and outputting for example:

Please enter a number: 20
10.500000

This number is correct, but only after one iteration.
this is the output that is at the bottom. of my code, where it outputs x_new

I also tested the number that I have from |x_old - x_new|/x_new
by putting it in a temp variable and outputting it and comparing to what I calculated using pencil and paper, and that is correct also.

Maybe the problem lies somewhere else? I am not sure at this point.

The reason for not just using fsqrt is that I am just learning the fpu programming, and I am trying to get myself used to programming in it by using different instructions with it.  

So, I may have logic errors someplace else in my code, but to me, it all looks correct.

Commented:
"jnc", sorry.
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
My whole problem in the task was a fdivr in place of a fdiv in my origional code...
I will give you the points, thank you for your help.
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.