我正在创建一个编译器(源代码是一种类似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函数工作而不对斐波纳奇函数工作吗?
第一个
1条答案
按热度按时间wlsrxk511#
您正在使用英特尔公司的32位双字进行整数运算。您要寻找的答案是1123581321345589144233377,它需要80位的无符号数,或81位的有符号数或11字节。如果您需要乘法,则需要22字节的乘积。或者你可以把两个11字节的数字放在内存中。在英特尔上使用你必须编写的软件进行更高位的运算是可能的。也许有你可以购买的软件,或者在公共领域。