プレミス MIPSのスタックは他のアーキテクチャのスタックと同じように機能します。そのためGoogleだけでも可能です。
は、メモリの任意の場所にスタックポイントを想定します
| xxx | xxx = Undefined
| xxx | <- $sp
| |
| | | Free area, stack moves down
| | V
は今だけfact(3)
、たとえば、呼び出しをシミュレートします。
コードのイメージを貼り付けたので、ここにコードは表示されません。コピー可能なコードにより、この答えがはっきりと分かります。
fact
を呼び出すたびに、リターンアドレスと引数がこの順序でプッシュされます。
fact
が0x1000にあり、fact
への呼び出しが0x1ffcにあるとします。
fact(3)
| xxx |
| xxx |
| 0x2000 | Return address to caller of fact(3)
| 3 | <- $sp Argument of fact(3)
| |
fact(2) called from fact(3)
| xxx |
| xxx |
| 0x2000 | Return address to caller of fact(3)
| 3 | Argument of fact(3)
| 0x1028 | Return address to L1+8 label
| 2 | <- $sp Argument of fact(2)
fact(1) called from fact(2)
| xxx |
| xxx |
| 0x2000 | Return address to caller of fact(3)
| 3 | Argument of fact(3)
| 0x1028 | Return address to L1+8 label
| 2 | Argument of fact(2)
| 0x1028 | Return address to L1+8 label
| 1 | <- $sp Argument of fact(1)
fact(0) called from fact(1)
| xxx |
| xxx |
| 0x2000 | Return address to caller of fact(3)
| 3 | Argument of fact(3)
| 0x1028 | Return address to L1+8 label
| 2 | Argument of fact(2)
| 0x1028 | Return address to L1+8 label
| 1 | Argument of fact(1)
| 0x1028 | Return address to L1+8 label
| 0 | <- $sp Argument of fact(0)
fact(0)
戻り値1を返し、スタックから2つのアイテムを削除します。
fact(0)
は最後の呼び出しであるため、他の呼び出しは変更されていません$ra
さらには$a0
(引数)は必要ありません。したがって、スタックに保存されたこれらの2つの値は単に$sp
をインクリメントして破棄されます。
Just before "jr $ra" in fact(0)
| xxx |
| xxx |
| 0x2000 | Return address to caller of fact(3)
| 3 | Argument of fact(3)
| 0x1028 | Return address to L1+8 label
| 2 | Argument of fact(2)
| 0x1028 | Return address to L1+8 label
| 1 | <- $sp Argument of fact(1)
他のリターンはn*fact(n-1)
を計算し、その呼び出し元に戻るには、スタックから$a0
と$ra
の値を復元します。スタックは再帰鎖の末端に元の位置に戻される方法
Just before "jr $ra" in fact(1)
| xxx |
| xxx |
| 0x2000 | Return address to caller of fact(3)
| 3 | Argument of fact(3)
| 0x1028 | Return address to L1+8 label
| 2 | <- $sp Argument of fact(2)
Just before "jr $ra" in fact(2)
| xxx |
| xxx |
| 0x2000 | Return address to caller of fact(3)
| 3 | <- $sp Argument of fact(3)
Just before "jr $ra" in fact(3)
| xxx |
| xxx | <- $sp
注意。
あなたはそれについてかなり説明しました。これらの2つの値は、呼び出しが行われるたびにスタックに格納されます。これはスタックなので、メモリの線形ブロックです。どのようにしてそれをもっと明確にすることができないのか分かりません。 –
それぞれの再帰呼び出しの写真はすばらしく、アイデアについて100%自信を持っています –