Recursion 调用方和被调用方的递归斐波那契函数(x86汇编)
我试图编写一个递归函数,返回斐波那契序列中的第n个数字(1,1,2,3,5,…) 我有点困惑,因为这个函数在正常的调用约定中既是调用者又是被调用者,而且是递归的。到目前为止,我的代码输出每个案例的输入(n)Recursion 调用方和被调用方的递归斐波那契函数(x86汇编),recursion,assembly,x86,calling-convention,Recursion,Assembly,X86,Calling Convention,我试图编写一个递归函数,返回斐波那契序列中的第n个数字(1,1,2,3,5,…) 我有点困惑,因为这个函数在正常的调用约定中既是调用者又是被调用者,而且是递归的。到目前为止,我的代码输出每个案例的输入(n) push ebp mov ebp, esp push edx push ecx push eax push ebx push esi push edi
push ebp
mov ebp, esp
push edx
push ecx
push eax
push ebx
push esi
push edi
//body
mov ecx, [ebp + 8] // n parameter
cmp ecx, 2
jge Else
mov eax, 1
jmp Epilouge
Else:
//mov edx, ecx // save n
dec ecx
push ecx
call fibonacci
add esp, 4
mov ebx, eax // move first returned result into ebx
sub ecx, 2
push ecx
call fibonacci
add esp, 4
add eax, ebx // add the two returned values
Epilouge:
pop edi
pop esi
pop ebx
pop eax
pop ecx
pop edx
pop ebp
您的代码有几个问题:
由于
eax
用于返回函数值,因此可以有效地防止函数返回任何值子ecx,2
应该是子ecx,1
否则,计算f(n)=f(n-1)+f(n-3),它不是斐波那契函数,类似于单位映射
jge
代替jae
(有效地添加初始条件f(k)=1,∀k<2)否则f(-1)将被视为f(232-1)
最后,我假设结尾不见了
ret
由于一个简单的复制粘贴错误。您的代码有几个问题:
由于
eax
用于返回函数值,因此可以有效地防止函数返回任何值子ecx,2
应该是子ecx,1
否则,计算f(n)=f(n-1)+f(n-3),它不是斐波那契函数,类似于单位映射
jge
代替jae
(有效地添加初始条件f(k)=1,∀k<2)否则f(-1)将被视为f(232-1)
最后,我假设结尾不见了
ret
由于一个简单的复制粘贴错误。请更正复制粘贴错误。我取出了推/弹出eax,并将子eax更改为1。成功了!你介意解释一下jae是什么以及为什么不使用它是好的吗?@user6313136
jae
是jge的未签名版本。这还不错,但在最初的实现中,fibonacci(2)=fibonacci(1)+fibonacci(-1)必须处理有符号的数字。使用jge
-1不大于等于2,使用jae
-1(0ffffffh无符号)大于等于2;从而将fibonacci(-1)
转换为fibonacci(0ffffffh)=fibonacci(4.294.967.295)=fibonacci(2^32-1)
更正复制粘贴错误。我取出了推/弹出eax,并将子eax更改为1。成功了!你介意解释一下jae是什么以及为什么不使用它是好的吗?@user6313136jae
是jge的未签名版本。这还不错,但在最初的实现中,fibonacci(2)=fibonacci(1)+fibonacci(-1)必须处理有符号的数字。使用jge
-1不大于等于2,使用jae
-1(0ffffffh无符号)大于等于2;从而将fibonacci(-1)
转换为fibonacci(0ffffffh)=fibonacci(4.294.967.295)=fibonacci(2^32-1)