所以这是一个使用递归的Fibonacci程序, 但最后有一个“分段错误(代码转储)”。是什么导致这个? 代码:
_start:
mov eax, 4 ; ask for a number
mov ebx, 1
mov ecx, prompt
mov edx, promptLen
int 80h
mov eax, 3 ; scan input
mov ebx, 0
mov ecx, n
int 80h
sub byte [n], 30h
mov esi, 1
push word 0
push word [n]
call fibo
exit:
mov eax, 1
mov ebx, 0
int 80h
fibo:
mov ebp, esp
mov edi, [ebp+6]
add byte [ebp+6],30h
mov eax, 4 ; print number
mov ebx, 1
lea ecx, [ebp+6]
mov edx, 1
int 80h
sub byte [ebp+6],30h
mov eax, 4 ; print space
mov ebx, 1
mov ecx, space
mov edx, 1
int 80h
cmp byte [ebp+4],0
je bye
add [ebp+6],esi
mov esi, edi
push word [ebp+6]
dec word [ebp+4]
push word [ebp+4]
call fibo
bye:
ret 4
sampe输出:
Enter a number: 5
0 1 1 2 3 5 Segmentation fault (code dumped)
输出数字是否正确但导致seg错误的原因是什么?
答案 0 :(得分:0)
我看不到你弹出或添加任何值到esp。请确保esp与呼叫开始时的值相同。您可以通过将基指针保存在堆栈上来实现。 在每个功能中记得这样做:
push ebp
mov ebp,esp
;at the end of the function
pop ebp
在调用推送某些寄存器的函数后,请务必执行以下操作:
add esp, 4*x
;where x is the number of registers you pushed.
答案 1 :(得分:0)
你在32位堆栈上推文字。这是“合法的”,但可能是一个坏主意。你“可能”只是让它发挥作用,但add [ebp + 6], esi
正在杀死你。这是堆栈中的4个字节,而不仅仅是你想要的2个字节。只需将其更改为si
“可能会”修复它,但我建议您始终使用dwords。你的ret 4
正在从堆栈中删除2个(word!)参数 - 这是“stdcall”,这在Linux中很常见,但“应该”有效。我就像coolbartek所展示的那样。