汇编语言--递归
程序员文章站
2022-04-22 10:53:27
...
举例说明:
1. 计算5!
.code
main PROC
; mov EBX, 6
push 5 ; calculate 5 factorial
call Factorial ; calculate factorial (eax)
call WriteDec ; display it
call Crlf
; mov EAX, EBX
; call WriteInt
exit
main ENDP
Factorial PROC
push ebp
mov ebp,esp
mov eax,[ebp+8] ; get n
cmp eax,0 ; n < 0?
ja L1 ; yes: continue
mov eax,1 ; no: return 1
jmp L2
L1: dec eax
push eax ; Factorial(n-1)
call Factorial
; Instructions from this point on execute when each
; recursive call returns.
ReturnFact: ; 这一行是为了提示我们执行到call指令之后会自动保存returnfact的地址
mov ebx,[ebp+8] ; get n
mul ebx ; ax = ax * bx
L2:
pop ebp ; return EAX
ret 4 ; clean up stack
Factorial ENDP
END main
以上代码的堆栈情况如下图所示
2. Convert the following pseudo code to assembly. Assume parameters are passed on the stack, and the return value is in eax!
fib ( int n ) {
if ( n <= 1 ) return 1;
else return fib(n-1) + fib(n-2);
}
fib PROC
push ebp ;假设n = 3
mov ebp, esp
mov eax, [ebp + 8]
cmp eax, 1
jnbe L1
mov eax, 1
jmp done
L1:
dec eax
push eax
call fib ; fib( n - 1 )
push eax ; fib( n - 1 ) 进栈
mov eax, [ebp + 8]
sub eax, 2
push eax
call fib ; fib( n - 2 )
pop ebx ; ebx = 2
add eax, ebx ; eax = eax + ebx = 1 + 2
done:
pop ebp
ret 4
fib ENDP
下图所示的是上面代码段的堆栈情况
栈中左边被划去的是第一个 call fib 的情况,当代码执行到 call 函数时,机器会自动将下一条命令 push 进栈中,然后不断递归直到 n=1 时跳转去 done 中的代码,pop ebp,找到 return2 中保存的地址 并且清除变量 eax3,然后往上继续 pop ebp1, 最后将eax1从栈中清除,然后栈中只剩下最上面3行,此时寄存器 eax = 2 ,再将其 push 进栈来保存 fib( n - 1 ) 的值, 注意,此时 ebp + 8 这个地址中的数据依然是 n
上一篇: XMemcached发布1.1.3