Почему у меня возникает ошибка сегментации в рекурсивной функции сборки?
Привет, я пишу рекурсивный код Фибоначчи в сборке с соглашением о вызовах amd64 abi, но всегда получаю ошибку сегментации:/ Я компилирую его с помощью:
nasm -f elf64 -o fibo.o fibonacci.asm
ld -o fibo fibo.o
./fibo
У меня нет ошибок компиляции, но есть ошибка сегментации, поэтому я думаю, что что-то пошло не так с моими Stackframes.
Спасибо за любую помощь:)
SECTION .data
; define the fibonacci number that should be calculated
n: dq 10
SECTION .text
global _start
_start:
; call Fibonacci function f(n)
mov rdi, [n] ; parameter: fibonacci number to calculate
call f ; call function
; print calculated Fibonacci number on stdout
;call printnumber
; exit process with exit code 0
mov rax, 60
mov rdi, 0
syscall
; f: Calculates a Fibonacci number
; f(n) = {n, if n<=1; f(n-1)+f(n-2), else}.
; Parameter: Integer n >= 0, passed on stack
; Returns: Fibonacci number f(n), returned in rax
f:
push rbp ; neuen stackframe
mov rbp, rsp
push rdi ; rdi auf stack speichern
add rbp, 16 ;
mov rdi, [rbp] ; rdi = parameter
cmp rdi, 1 ; check for base case
jle base ; n <= 1
dec rdi ; n-1
push rdi
call f ; f(n-1)
pop rdi
dec rdi ; n-2
push rdi
call f ; f(n-2)
pop rdi
pop rdi
add rax, rdi
jmp end
base:
mov rax, 1
end:
pop rdi
pop rbp
mov rsp, rbp
ret
1 ответ
Вы устанавливаете фрейм стека в f
правильно, но затем вы начинаете ошибаться с добавлением rbp
. Ты должен уйтиrbp
в одиночку и вместо этого добавьте смещение к выборке переменной:
push rdi
move rdi,[rbp+16]
Вы выходите из неправильной последовательности. Добавление 16 к rbp в записи является проблемой здесь (решается без изменения rbp), и у вас естьrsp
восстановление в неположенном месте.
pop rdi
mov rsp,rbp ; Unnecessary here (see below)
pop rbp
ret
Однако, поскольку вы никогда не меняетесь rsp
чтобы выделить хранилище для локальных переменных, перейдите к rsp
не является необходимым и может быть опущено.
Обратите внимание, что есть другие проблемы с кодом, не связанные с последовательностью входа / выхода и сбоя.