I am trying to write an assembly version of the C program below. It is meant to take the square root of 9. Everything seems to be working until the 3rd pass through my loop, and then my values for upper and lower become 1#IND when pushed to the stack. I don't know why because it correctly prints just below the label whileLoop, but I get the wrong values the second time it is printed directly after the label notAccurateEnough, even though the values don't change between these two labels and it worked fine on the previous iterations.
Below are screenshots that show how it successfully prints once, then fails to print the second time in the same iteration.
Assembly Code:
.586
.MODEL FLAT
.STACK 4096
n=550
.data
PUBLIC _sqrtX
upper REAL4 9.0
accuracy REAL4 0.00001
lower REAL4 1.0
guess REAL4 1.0
multValue REAL4 1.0
num REAL4 9.0
two DWORD 2
.code
_sqrtX PROC
finit ;initialize fpu
whileLoop:
fld upper ;push upper onto stack
fld lower ;push lower onto stack
fsub ;subtract upper-lower
fld accuracy ;push accuracy onto stack
fcom ;compare accuracy with upper-lower
fstsw ax ;copy condition code bits to AX
sahf ;shift condition code bits to flags
jna notAccurateEnough ;jump if accuracy is greater
jmp endnewt ;end algorith, is less than accuracy
notAccurateEnough:
;**************************
;************ Logic to implement: guess = (lower + upper) / 2;
;**************************
fld upper ;push upper onto stack
fld lower ;push lower onto stack
fadd ;(lower + upper)
fidiv two ;divide by 2
fstp guess ;set guess to first stack element. guess = (lower + upper) / 2
;**************************
;**************************
;************ Logic to implement: if((guess * guess) > number)
;**************************
fld guess ;push guess onto stack as first element
fld guess ;push guess onto stack again, it is now first and second element
fmul ;multiply first and second element
fcom num ;compare 9 to product of guess*guess:
fstsw ax ;copy condition code bits to AX
sahf ;shift condition code bits to flags
jna SetLower ;if guess is less than num, call set lower and set lower = guess;
;*** else, guess > num
fld guess ;push guess onto the stack
fstp upper ;set upper equal to top of stack: upper = guess
jmp whileLoop
;**************************
setLower:
fld guess ;push guess onto stack
fstp lower ;store guess in lower
jmp whileLoop
endnewt:
mov eax, 0
ret
_sqrtX ENDP
END
C algorithm I am trying to write in Assembly:
double sqrtX (double x)
{
const double ACCURACY=0.00001;
double lower, upper, guess;
double number;
number = x;
lower = 1;
upper = number;
while ((upper-lower) > ACCURACY)
{
guess = (lower + upper) / 2;
if((guess * guess) > number)
{
upper = guess;
}
else
{
lower = guess;
}
}
return (lower + upper)/2;
}
Had stack overflow. Cleared the stack after each iteration with finit
and now it works.