Assembly 使用间接递归的_-cdecl问题
我写了一个阶乘计算程序,一直到最后的计算。在计算Assembly 使用间接递归的_-cdecl问题,assembly,cdecl,Assembly,Cdecl,我写了一个阶乘计算程序,一直到最后的计算。在计算\u multiply\u fact中的阶乘值时,基指针最终指向一个随机值。我做错了什么 召唤 push n call _factorial add esp, 4 程序 _factorial: push ebp ;save base pointer mov ebp, esp ;set up new base pointer mov ebx, 8[ebp] cmp ebx, 1
\u multiply\u fact
中的阶乘值时,基指针最终指向一个随机值。我做错了什么
召唤
push n
call _factorial
add esp, 4
程序
_factorial:
push ebp ;save base pointer
mov ebp, esp ;set up new base pointer
mov ebx, 8[ebp]
cmp ebx, 1 ;while n > 0
jg _multiply_fact ;decrement n
mov eax, 1 ;if n == 0 ret 1
pop ebp
ret ;return to multipy_fact for calculation
_multiply_fact:
pop ebp
push ebp
mov ebp, esp
mov ebx, 8[ebp]
dec ebx ;decrements n-1 times
push ebx
call _factorial
inc ebx
mul ebx ;recursively multiplies eax * (n+1)
pop ebp
ret
好的,在进行了更多的故障排除之后,我发现这个错误是因为我忘了包括
add esp, 4
正如您所说,在我在_multiply _fact过程中调用_factorial之后,阻止它工作的错误是在递归调用之后没有修复堆栈。但这并不是唯一的错误
\u multiply\u fact
实际上不是一个函数。它只是\u factorial
代码的一部分,当您不提前退出n0)时,它会运行。请注意,dec没有设置CF,所以如果您想将其转换为无符号,只需使用jnz而不是ja
;; 基本情况
mov-eax,1;如果(n)
global _factorial
_factorial:
; one arg: int n
push ebp
mov ebp, esp ; make a stack frame
mov edx, [ebp + 8] ; load first arg into a scratch reg
dec edx
jg .multiply_fact ; if ((n-1) > 0). Note that dec doesn't set CF, so just use jnz instead of ja if you want to convert this to unsigned
;; base case
mov eax, 1 ;if (n <= 1) ret 1
pop ebp
ret
.multiply_fact: ; not a separate function, still part of _factorial
; in NASM, .labels are local labels that don't show up as symbols in the object file. MASM uses something different.
; at this point: edx = n-1
push edx
call _factorial ; eax = fac(n-1)
pop edx ; get n-1 back off the stack. Taking advantage of extra knowledge of our own internals, since the ABI allows functions to clobber their args on the stack
; add esp, 4 not needed, because we popped instead
inc edx ; undo the earlier dec before we pushed
imul eax, edx ; n * fac(n-1). 2-arg imul runs faster
pop ebp
ret