linux - Understanding recursive factorial function in NASM Assembly -
learning nasm assembly on 32-bit ubuntu. i'm trying learn recursive functions, starting factorial (note: here assuming parameter non-negative).
assuming have
push 3 call factorial
i want end 6
in eax
.
here attempt:
section .text global main main: ; ----------------------------------------------------------- ; main ; ----------------------------------------------------------- push 3 call factorial ; ----------------------------------------------------------- ; exit ; ----------------------------------------------------------- mov eax,1 int 0x80 ; ----------------------------------------------------------- ; recursive factorial: n! = n * (n - 1)! ; ----------------------------------------------------------- factorial: push ebp ; retrieve parameter , put mov ebp,esp ; ebx register add ebp,8 ; mov ebx,[ebp] ; ebx = param cmp ebx,0 ; check base case je base ; base if (n == 0) dec ebx ; decrement ebx put in stack push ebx ; put (ebx - 1) in stack inc ebx ; restore ebx call factorial ; calculate factorial (ebx - 1) mul ebx ; eax = (eax * ebx) = (ebx - 1)! * ebx pop ebx ; retrieve ebx stack jmp end base: ; base case mov eax,1 ; result 1 end: pop ebp ; release ebp ret
at least works base case, ha... other value push, returns 0
. had suspicion maybe since eax
0
, mul
result in 0
, explaining this. test, decided give eax
value of 2
, expecting non-zero value, kept resulting in 0
.
can advice me on how recursive factorial function takes parameter stack? believe having seen examples, either not recursive or took parameters other places, or used bunch of variables (when think can done registers).
note factorial(n-1)
overwrite factorial(n)'s
value of ebx
first thing does, thereby rendering inc ebx
after push
pointless. after you've reached base case you'll have situation ebx
0 when mul
, , of course * 0 == 0.
the easiest fix change prologue to:
push ebp ; retrieve parameter , put push ebx ; save previous param mov ebp,esp ; ebx register add ebp,12 ; mov ebx,[ebp] ; ebx = param
and epilogue to:
pop ebx ; restore previous param pop ebp ; release ebp ret
Comments
Post a Comment