NASM 程序:递归分割错误



所以这是一个使用递归的斐波那契程序,但最后有一个"分段错误(代码转储)"。这是什么原因造成的?代码:

_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

采样输出:

Enter a number: 5
0 1 1 2 3 5 Segmentation fault (code dumped)

输出数字是正确的,但是什么原因导致SEG故障?

我看不到您弹出或向 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.

您正在 32 位堆栈上推送单词。这是"合法的",但可能是一个坏主意。你"可能"只是让它工作,但add [ebp + 6], esi是杀戮你。这是在堆栈上破坏 4 个字节,而不仅仅是您想要的 2 个字节。只是将其更改为si"可能"修复它,但我建议始终使用 dwords。您的ret 4正在从堆栈中删除 2 个(word!) 参数 - 这是"stdcall",这在 Linux 中是不寻常的,但"应该"工作。我会按照酷巴特克展示的方式去做。

相关内容

  • 没有找到相关文章

最新更新