Author Topic: Factorial with doubles  (Read 20290 times)

Offline sultanofswing.90

  • Jr. Member
  • *
  • Posts: 3
Factorial with doubles
« on: July 01, 2010, 01:59:25 PM »
Hi  :D i'm trying to write a procedure to calculate the factorial using doubles numbers, and I've got a lot a problems:

here's the function:
Code: [Select]
;double_factorial(double* a,double* result)
double_factorial:
enter 0,0
push eax
push ebx
mov eax,dword[ebp+8]
mov ebx,dword[ebp+12]
fld1
fstp dword[ebp-4]
fld qword [eax]
LP:
fld qword [eax]
fsub dword[ebp-4]
fld1
fcomi st1
je fact_done
fcomp st0
fst qword [eax]
fmulp st1
jmp LP
fact_done:
fcomp st0
fcomp st0
fstp dword[ebx]
pop ebx
pop eax
leave
ret

there's no problem when i call this function from a file(ex. double_factorial(&n,&p),n and p are both double), but what i've to do if i want to call double_factorial from another asm function? For example:
Code: [Select]
mytest:
enter 0,0

push dword[ebp+8]
push dword[ebp+12]
call double_factorial
add esp,8

leave
ret
assuming that both [ebp+8] and [ebp+12] are double pointers(4byte), this procedure doesn't work! Why? Another question is: how can i create a local variable(double) in the asm code? Double is a 8byte data, and i can't put it on the stack!... ??? ???

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Factorial with doubles
« Reply #1 on: July 01, 2010, 03:06:48 PM »
Hmmm... I dunno. Looks to me that in "double_factorial", you're using a local variable at ebp - 4 without reserving any space for it. You might want "enter 4, 0" (or maybe "enter 16, 0" for better stack alignment?). I don't think that's causing a problem. Also, comparing floats for equality is "iffy". Since you're interested in 1.0, that probably isn't a problem, either(?).

I'm not sure what you're doing with "mytest". You seem to be swapping "number" and "result". Is that intentional? (or maybe that's your problem?) I think we'd need to see the caller of "mytest" to know.

In order to put a double on the stack, either as a parameter or a local variable, you could do it with two pushes:

Code: [Select]
push dword [my_double + 4]
push dword [my_double]

or probably better(?):

Code: [Select]
fld qword [my_double]
sub esp, 8
fstp qword [esp]

If I get around to playing with your code, I might have a better answer, but that's all I can think of right now. The only "factorial" program I've done has used integers - it'll only do up to 20! before overflowing 64 bits.

Best,
Frank


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Factorial with doubles
« Reply #2 on: July 01, 2010, 06:19:16 PM »
fstp dword [ebx] -> fstp qword [ebx]

Seems to help with my homemade caller. You did intend "result" to be a double, right? Only seems to work up to 18!, though - may be a problem with my caller.

Best,
Frank


Offline sultanofswing.90

  • Jr. Member
  • *
  • Posts: 3
Re: Factorial with doubles
« Reply #3 on: July 01, 2010, 09:11:31 PM »
hmmm so i have to do a "dirty job" with the stack!  :o ;D

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Factorial with doubles
« Reply #4 on: July 02, 2010, 01:32:38 AM »
Huh? Well, yeah... I did change "enter 0, 0" to "enter 4, 0", also. You were overwriting ebx with that local variable where you were storing the 1.0. Doesn't matter to my homemade caller, but it might if you were calling it from C (unless you preserve ebx elsewhere). Just change "dword" to "qword" where you write the result back. Or, you could treat "result" as single-precision, but that would limit your range. "Factorial" grows quite rapidly! :)

My code is "Linux only". You want it, or do you need something "portable"? That could be easily (famous last words) arranged. The only "Linux only" part is writing the result to stdout. If you use C, you wouldn't need my homemade "ftoa". However, "printf" expects a double on the stack (even if you say "%f", it's a double!) - that's why I don't like C - too much "hidden" cruft!

Best,
Frank


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Factorial with doubles
« Reply #5 on: July 02, 2010, 02:11:51 AM »
FWIW, I just tried a "C caller". My homemade "ftoa" was limiting the range. :( Printf will handle bigger numbers! My executable was smaller, though. :)

Best,
Frank


Offline sultanofswing.90

  • Jr. Member
  • *
  • Posts: 3
Re: Factorial with doubles
« Reply #6 on: July 02, 2010, 08:42:03 AM »
Well, now it's working. Thanks  :D  :P