Recursion 调用方和被调用方的递归斐波那契函数(x86汇编)

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

我试图编写一个递归函数,返回斐波那契序列中的第n个数字(1,1,2,3,5,…)

我有点困惑,因为这个函数在正常的调用约定中既是调用者又是被调用者,而且是递归的。到目前为止,我的代码输出每个案例的输入(n)

        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。
    由于
    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
    用于返回函数值,因此可以有效地防止函数返回任何值

  • 子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是什么以及为什么不使用它是好的吗?@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)