assembly 递归斐波纳契数列

3vpjnl9f  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(184)

我正在创建一个编译器(源代码是一种类似C的语言,我正在将其翻译为x86 NASM)。
我用递归函数测试了我的编译器,除了这个斐波纳契函数,它们都有预期的结果。
我知道我的代码根本没有优化,我会在以后修复它。
有人能告诉我ASM代码有什么问题吗?如果我打印从0到13的斐波那契数列,输出应该是:
1123581321345589144233377
但我得到的是1123354759611713
或者如果我格式化它的话1,1,2,3,3,5,4,7,5,9,6,11,7,13
有人能告诉你哪里出了问题吗?源代码是:

int f
//global var f
 
int fibonacci( int n ){
    if ((n=0) or (n=1)){
        return 1
    }
    else{
        return fibonacci(n-1) + fibonacci(n-2)
    }
}
 
 
 
main(){
    f = fibonacci(6)
    print(f)
}

ASM代码为:

;fibonacci (not optimized)
extern printf
global main
section .data
format db '%d', 0
 
f dd 0
 
temp0 dd 0
temp1 dd 0
temp2 dd 0
temp3 dd 0
temp4 dd 0
temp5 dd 0
temp6 dd 0
temp7 dd 0
temp8 dd 0
temp9 dd 0
temp10 dd 0
temp11 dd 0
temp12 dd 0
 
section .text
fibonacci:
push ebp
mov ebp, esp
 
;eq expr
mov dword[temp0], 0
mov eax, dword[ebp + 8]
cmp eax, dword[temp0]
mov eax, 0
sete al
mov dword[temp0], eax
 
;eq expr
mov dword[temp1], 1
mov eax, dword[ebp + 8]
cmp eax, dword[temp1]
mov eax, 0
sete al
mov dword[temp1], eax
 
;or expr
cmp dword[temp0], 1
je label1
cmp dword[temp1], 1
je label1
mov dword[temp2], 0
jmp label2
label1:
mov dword[temp2], 1
label2:
 
;ifStmt
cmp dword[temp2], 0
je label3
;return statement
mov dword[temp3], 1
mov eax, dword[temp3]
;jmp to epilogue
jmp label0
 
jmp label4
;else label
label3:
 
;return statement
 
mov dword[temp5], 1
mov esi, dword[ebp + 8]
sub esi, dword[temp5]
mov dword[temp6], esi
 
push dword[temp6]
;subprogram call
call fibonacci
add esp, 4
mov dword[temp4], eax
 
 
mov dword[temp8], 2
mov esi, dword[ebp + 8]
sub esi, dword[temp8]
mov dword[temp9], esi
 
push dword[temp9]
;subprogram call
call fibonacci
add esp, 4
mov dword[temp7], eax
 
mov esi, dword[temp4]
add esi, dword[temp7]
mov dword[temp10], esi
 
mov eax, dword[temp10]
;jmp to epilogue
jmp label0
 
label4:
 
label0:
pop esi
mov esp, ebp
pop ebp
ret
 
main: 
mov dword[temp12], 6
push dword[temp12]
;subprogram call
call fibonacci
add esp, 4
mov dword[temp11], eax
 
 
mov eax, dword[temp11]
mov dword[f], eax
 
push dword[f]
push format
call printf
add esp, 8
 
ret

有人能解释一下为什么我的编译器只对gcd函数工作而不对斐波纳奇函数工作吗?
第一个

wlsrxk51

wlsrxk511#

您正在使用英特尔公司的32位双字进行整数运算。您要寻找的答案是1123581321345589144233377,它需要80位的无符号数,或81位的有符号数或11字节。如果您需要乘法,则需要22字节的乘积。或者你可以把两个11字节的数字放在内存中。在英特尔上使用你必须编写的软件进行更高位的运算是可能的。也许有你可以购买的软件,或者在公共领域。

相关问题