Assembly IA32汇编中的递归阶乘函数
我一直试图让IA32汇编中的递归阶乘函数正常工作,但我得到的阶乘总是比我在函数中传递的要少 5的阶乘是120,但我得到24,这是4的阶乘 我目前的情况如下: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
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]