Я пытаюсь написать классическую функцию fib (n) в сборке (intel x86) , которая возвращает n-й элемент последовательности Фибоначчи.
Я написал итерационную версию довольно легко, но у меня возникают проблемы при попытке рекурсии. Вот что я попробовал:
.intel_syntax noprefix
.text
# unsigned fib(unsigned)
.globl fib
fib_n:
enter 0, 0
mov eax, 0
# n = 0 or n = 1
cmp edi, 1
jbe end
mov eax, 1
# n == 2
cmp edi, 2
je end
# n > 2, entering recursion
# fib(n-1)
push rdi
dec edi
call fib_n
mov r8d, eax
pop rdi
# fib(n-2)
push rdi
sub edi, 2
call fib_n
mov r9d, eax
pop rdi
# fib(n) = fib(n-1) + fib(n-2)
mov eax, r8d
add eax, r9d
end:
leave
ret
Я ожидаю, что вызовы, отмеченные # fib (n-1) и # fib (n-1) для хранения local eax , приводят к r8d и Регистрирует r9d, а затем просто добавляет их и возвращает через eax, но вот что я получаю в качестве вывода:
n = 1 (1-й эл): 0 (работает нормально)
n = 2: 1 (работает нормально)
n = 3: 1 (работает нормально)
(неверные результаты)
n = 4: 2
n = 5: 2
n = 6: 3
n = 7: 3
...
Я также пытался выдвинуть rax в стек и rdi, но я все еще получаю неправильные результаты. Чего мне не хватает?