gpt4 book ai didi

linux - 递归斐波那契组装

转载 作者:太空宇宙 更新时间:2023-11-04 12:17:34 25 4
gpt4 key购买 nike

今天我在汇编中写了一个递归的斐波那契,但它不起作用。我用 NASM 将它编译成目标文件,然后用 gcc 把它变成了 elf。
当我输入 1 或 2 时,该功能完美运行,但当我输入 3、4、5、6 或更多时,该功能不起作用。我认为函数调用自身存在问题。

这是代码:

SECTION .data ;init data




str: db "This equal: %d",10,0

SECTION .text ;asm code


extern printf
global main

main:
push ebp
mov ebp,esp
;--------------------


push 03 ; the index
call _fibonacci
add esp,4

push DWORD eax
push str
call printf


;---------------------

mov esp,ebp
pop ebp
ret

这是函数:

_fibonacci:

push ebp
mov ebp,esp


mov ebx, [ebp+8] ;; param n
cmp ebx,0
jne CHECK2

mov eax,0
jmp _endFIbofunc

CHECK2:
cmp ebx,0x1
jne ELSE3
mov eax,1
jmp _endFIbofunc

ELSE3:

mov ebx,[ebp+8]
dec ebx ;; n-1


;; FIRST call
push ebx
call _fibonacci
add esp,4
mov edx,eax

;; SEC CALL
dec ebx
push ebx
call _fibonacci
add esp,4
add eax,edx


mov eax,[ebp-4]

_endFIbofunc:

mov esp,ebp
pop ebp
ret

我在 Ubuntu 16.04 上运行它后它发送错误:

Segmentation fault (core dumped)

可能是什么问题?

最佳答案

mov eax,[ebp-4]

您正在使用 [ebp-4] 处的内存,但没有在其中放入有用的东西!您需要在函数序言中保留此空间:

_fibonacci:
push ebp
mov ebp, esp
sub esp, 4

从第一个递归调用返回,您将 EAX 的结果放入此内存 dword 中。
从第二次递归调用返回,您将此内存双字的内容添加到 EAX
这样做,EDX 寄存器将不再被破坏。


为什么要使用 EBX 寄存器?如果您使用它,则必须按照 Al Kepp 的回答中的解释保留它。 .
如果您首先将参数放入 EAX,您就会知道对于小于 2 的两个值(即 0 和 1),结果正好等于参数。简单。

    mov  eax, [ebp+8] ;; param n 
cmp eax, 2
jb _endFIbofunc

如果您在第一次递归调用后没有直接平衡堆栈,您可以只递减已经存在的双字并进行第二次递归调用。

    dec  eax              ; n-1
push eax ;(*)
call _fibonacci
mov [ebp-4], eax
dec dword ptr [esp] ; n-2
call _fibonacci
add esp,4 ;(*)
add eax, [ebp-4]

整个过程:

_fibonacci:
push ebp
mov ebp, esp
sub esp, 4 ;(*)
mov eax, [ebp+8] ;; param n
cmp eax, 2
jb _endFIbofunc
dec eax ; n-1
push eax ;(*)
call _fibonacci
mov [ebp-4], eax
dec dword ptr [esp] ;(*) n-2
call _fibonacci
add esp,4 ;(*)
add eax, [ebp-4]
_endFIbofunc:
mov esp, ebp
pop ebp
ret

关于linux - 递归斐波那契组装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47001872/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com