Reputation: 425
I have this assembly code(Linux 32Bit compiled with gcc -m32) and I do not really understand why my program doesn't work.
.data
.bla:
.ascii "%d\n\0"
.globl main
.text
main: pushl $4
call factorial
movl $1, %eax
ret
factorial:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
cmpl $1, %ecx
jg .rek
movl $1, %eax
movl %ebp, %esp
pop %ebp
ret
.rek:
decl %ecx
pushl %ecx
call factorial
addl $4, %esp
movl 8(%ebp), %ecx
imull %ecx, %eax
pushl %eax
pushl $.bla
call printf
addl $8, %esp
movl %ebp, %esp
pop %ebp
ret
Unfortunately every time a Segmentation Fault does occur + parameters bigger than 4 do not work.
This should be my stack when I run the program with "3":
3
ret add
ebp
2
ret add
ebp
1
ret add
ebp
When I reach the bottom of the recursion I take the return value saved in eax and multiply it with 8(%ebp) which should be the next value.
I really appreciate any help you can provide.
Upvotes: 1
Views: 2733
Reputation: 58244
Three issues I see.
1) Your call maine
(I'm assuming that was a typo, and you meant, main
) should be call factorial
2) In your main
program, you don't restore your stack pointer.
3) Your printf
call modifies %eax
and overwrites the result of your factorial
before it returns.
Repaired program:
.data
.bla:
.ascii "%d\n\0"
.globl main
.text
main: pushl $5
call factorial
addl $4, %esp # ADDED THIS
movl $1, %eax
ret
factorial:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
cmpl $1, %ecx
jg .rek
movl $1, %eax
movl %ebp, %esp
pop %ebp
ret
.rek:
decl %ecx
pushl %ecx
call factorial # FIXED THIS
addl $4, %esp
movl 8(%ebp), %ecx
imull %ecx, %eax
pushl %eax # ADDED THIS - SAVE RETURN VALUE
pushl %eax
pushl $.bla
call printf
addl $8, %esp # MODIFIED THIS
pop %eax # ADDED THIS (restore eax result)
movl %ebp, %esp
pop %ebp
ret
Upvotes: 1