In gdb you get SIGSEGV like this:
Program received signal SIGSEGV, Segmentation fault.
fibonacci () at f1.S:6
6 push %rax
What's more interesting is your backtrace (end of it):
(gdb) backtrace -10
#1048280 0x00007fffffffe6e0 in ?? ()
#1048281 0x000000000040056d in more () at f1.S:28
#1048282 0x00007fffffffe7fe in ?? ()
#1048283 0x00007fffffffe7ff in ?? ()
#1048284 0x00007fffffffe700 in ?? ()
#1048285 0x000000000040056d in more () at f1.S:28
#1048286 0x00007fffffffe7ff in ?? ()
#1048287 0x0000000000000006 in ?? ()
#1048288 0x00007fffffffe720 in ?? ()
#1048289 0x000000000040051f in main () at f2.c:7
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
So you managed to call your recursion 1 048 289 times...
Further more, after line 8 (movq 16(%rbp), %rax
), you'll get:
(gdb) i r rax
rax 0x7fffffffe800 140737488349184
And from your function it looks like rax
should be a counter.
Since you're using 64bit registers I assume you're running x86_64 architecture which doesn't store arguments on stack but uses registries:
If the class is INTEGER, the next available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9 is used
(gdb) i r edi
edi 0x6 6
Your solution would probably run fine on cdecl calling convention, but not on Microsoft x64 calling convention or System V AMD64 ABI.
So for example a way to get this done is (works for System V AMD64 ABI):
.global fibonacci
fibonacci:
push %rbp
push %rdi
cmp $0, %rdi
je zeroValue
cmp $1, %rdi
je oneValue
jmp more
zeroValue:
movq $0, %rax
jmp end
oneValue:
movq $1, %rax
jmp end
more:
dec %rdi
call fibonacci
push %rax
dec %rdi
call fibonacci
pop %r8
add %r8, %rax
end:
pop %rdi
pop %rbp
ret
Which goes like:
- store rbp
- store rdi
- if rdi == 0: return 0
- if rdi == 1: return 1
- decrease rdi
- call fibonacci
- store result on stack
- decrease rdi
- call fibonacci
- restore result to r8
- add r8 to result
- restore rdi
- restore rbp
And just out of curiosity, here's a version without recursion, just one loop (and few cases handling low values):
.global fibonacci
fibonacci:
cmp $2, %rdi # 2 and higher should be computer normally
jg compute
cmp $0, %rdi
jz zero
mov $1, %rax # 1st and 2nd elements = 1
ret
zero:
mov $0, %rax
ret
compute:
mov %rdi, %rcx # Use cpu counter register
sub $2, %rcx # The first number that will come out of this loop
# is 2, so decrease number of iterations
mov $1, %r8 # a = 1
mov $1, %r9 # b = 1
begin_iter:
mov %r9, %rax # sum = b
add %r8, %rax # sum += a
mov %r9, %r8 # a = b
mov %rax, %r9 # b = a
loop begin_iter
ret