繁体   English   中英

nasm程序:递归分段错误

[英]nasm program: recursion segmentation fault

因此,这是一个使用递归的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

样本输出:

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

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

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

您要在32位堆栈上压字。 这是“合法的”,但可能不是一个好主意。 你“可能”刚刚得到它的工作,但add [ebp + 6], esi是杀人雅。 这破坏了堆栈中的4个字节,而不仅仅是您想要的2个字节。 只是将其更改为si “可能”修复它,但我建议始终使用dword。 您的ret 4正在从堆栈中删除2个(word!)参数-这是“ stdcall”,在Linux中不常见,但“应该”可以工作。 我会按照coolbartek的方式来做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM