Assembly IA32汇编中的递归阶乘函数

Assembly IA32汇编中的递归阶乘函数,assembly,visual-c++,x86,Assembly,Visual C++,X86,我一直试图让IA32汇编中的递归阶乘函数正常工作,但我得到的阶乘总是比我在函数中传递的要少 5的阶乘是120,但我得到24,这是4的阶乘 我目前的情况如下: public factorial ; int factorial(int N) factorial: ; { push ebp ; push return addr mov ebp, esp

我一直试图让IA32汇编中的递归阶乘函数正常工作,但我得到的阶乘总是比我在函数中传递的要少

5的阶乘是120,但我得到24,这是4的阶乘

我目前的情况如下:

public factorial                ; int factorial(int N)
factorial:                      ; { 
    push ebp                    ;   push return addr    
    mov ebp, esp                ;   update SP

    mov eax, [ebp+8]            ;   N.getFromStack()
    dec eax                     ;       n--

    cmp eax, 0                  ;   if (N == 0)
    je n0                       ;   {

    push eax                    ;       push(n)
    call factorial              ;       factorial(n-1)
    pop ebx                     ;       pop result

    imul eax, ebx               ;       N*factorial(n-1)
    jmp re                      ;   }

n0: mov eax, 1                  ;   result = 1

re: mov esp, ebp                ;   update SP
    pop ebp                     ;   pop ret. addr.
    ret 0                       ;   return factorial(N) }

我做错了什么?

您正在破坏ebx,它是一个被调用方保存寄存器,因此调用它的代码可能会做一些奇怪的事情。您还将递归调用的返回值乘以该弹出值,而不是像您应该的那样乘以n

因此,将
pop ebx
替换为
add esp,4
,并将imul替换为
imul dword ptr[ebp+8]


通过去掉所有ebp/framepointer的东西,您可以使代码变得更小、更简单——在这样一个小的函数中,您不需要framepointer或frame;n--所以很明显你会少得到一个。另外,
push(n)
不能同时是
factorial(n-1)
。另外,
pop ebx
不是
pop result
,但这只是一个注释错误。最后,像往常一样,学习使用调试器。通过删除
pop ebx
并将
imul eax,ebx
更改为
imul eax,[ebp+8]
通过删除
pop ebx
并将
imul eax,ebx
更改为
imul eax,[ebp+8]