32 ビット Ubuntu での NASM アセンブリの学習。私は今、階乗から始めて、再帰関数について学ぼうとしています (注: ここでは、パラメーターが常に負でないことを前提としています)。
私が持っていると仮定すると
push 3
call factorial
6
で終わりたいEAX
。
これが私の試みです:
SECTION .text
global main
main:
; -----------------------------------------------------------
; Main
; -----------------------------------------------------------
push 3
call factorial
; -----------------------------------------------------------
; Exit
; -----------------------------------------------------------
mov EAX,1
int 0x80
; -----------------------------------------------------------
; Recursive Factorial: n! = n * (n - 1)!
; -----------------------------------------------------------
factorial:
push EBP ; Retrieve parameter and put it
mov EBP,ESP ; into EBX register
add EBP,8 ;
mov EBX,[EBP] ; EBX = Param
cmp EBX,0 ; Check for base case
je base ; It is base if (n == 0)
dec EBX ; Decrement EBX to put it in the stack
push EBX ; Put (EBX - 1) in stack
inc EBX ; Restore EBX
call factorial ; Calculate factorial for (EBX - 1)
mul EBX ; EAX = (EAX * EBX) = (EBX - 1)! * EBX
pop EBX ; Retrieve EBX from the stack
jmp end
base: ; Base case
mov EAX,1 ; The result would be 1
end:
pop EBP ; Release EBP
ret
少なくとも基本ケースでは機能しますが、私がプッシュする他の値では、常に を返します0
。私はおそらくそれ以来、常に結果EAX
が0
になるのではないかと疑っていました。テストするために、ゼロ以外の値を期待して の値を与えることにしましたが、結果は.MUL
0
EAX
2
0
スタックからパラメーターを取得する再帰階乗関数の実行方法についてアドバイスをいただけますか? いくつかの例を見たことがあると思いますが、それらは再帰的ではないか、他の場所からパラメーターを取得したか、または一連の変数を使用していました (レジスターだけで実行できると思います)。