関数を再帰的に呼び出す機能は、プロセッサまたはプログラミング言語/コンパイラに固有の機能です。おそらく、両方とも再帰をサポートするための要素が必要ですか?
関数を再帰的に呼び出す機能は純粋にプログラミング言語で実装されており、いつどこに戻るかについては、ランタイムスタックをどのようにレイアウトするかという印象を常に受けています。私はそう仮定するのは正しいですか、それともプロセッサには再帰を可能にする特定のロジックがありますか?
関数を再帰的に呼び出す機能は、プロセッサまたはプログラミング言語/コンパイラに固有の機能です。おそらく、両方とも再帰をサポートするための要素が必要ですか?
関数を再帰的に呼び出す機能は純粋にプログラミング言語で実装されており、いつどこに戻るかについては、ランタイムスタックをどのようにレイアウトするかという印象を常に受けています。私はそう仮定するのは正しいですか、それともプロセッサには再帰を可能にする特定のロジックがありますか?
プロセッサは、コードが指示する場所にジャンプするだけです。再帰は間違いなく言語関数です。
コンパイラが言語を実装する必要がある限り、これもコンパイラ関数です。しかし、そうでなかった場合は、壊れていると見なします。
最後に、もちろん、操作の負担はプロセッサが負担します。スタックフレームでコンテキストと変数をプッシュし、ルーチンのエントリポイントにジャンプし、命令を実行し、戻る必要があります...ご存知のとおり、プロセッサが行うこと。
最新のプロセッサはすべて、スタックベースの関数呼び出しおよび戻り命令を備えているため、再帰が可能です。
以前のコンピューターは非常に困難な時期にありました。たとえば、IBM 360は、関数の戻り値とローカル変数がコードと一緒になるようにコードをレイアウトしました。再帰呼び出しは、前の呼び出しの値を壊してしまいます。
言語。
再帰するために常にスタックが必要なわけではありません。スタックを必要としない再帰のタイプの例については、末尾再帰を参照してください。
Carl Smotriczが言ったように、CPUは命令ストリームで発生する分岐命令に従うだけです。私たちが再帰と呼ぶ傾向があるのは、通常の関数呼び出しにすぎません。呼び出される関数は、現在実行されている関数と同じであり、高レベルでは、いくつかの非常に興味深い効果があります。
スタックアドレッシングモードを備えた最新のプロセッサでも、OS / 360などのシステムで行われていたように、ヒープにコールフレームを割り当てたい場合があります。たとえば、Schemeでは、継続(基本的には呼び出しフレームとアクティブなローカル変数バインディングの表現)をキャプチャして保持することができます。関数内のグローバル変数で継続をキャプチャし、その関数から戻ると、アクティブな呼び出しフレームをクリーンアップできません。参照がなくなると、ある時点でガベージコレクターによってクリーンアップされますが、その間に、呼び出しフレームがスタックに割り当てられている場合は、別の場所(ヒープ)にコピーする必要があります。これは、再帰呼び出しにスタックフレームを割り当てる必要がないことを証明できる、末尾呼び出しの最適化の一種です。
スタックと再帰呼び出しの明示的なハードウェアサポートは必要ありませんが、プロセッサには特定の機能が必要です。レジスタベースのマシンでは、次で十分だと思います。
ブートストラップコードは、スタックとして使用するメモリの領域を割り当てる必要があります。
いくつかのプロセッサはこれを提供していないと思います。ほとんどのプロセッサは、スタックポインタとリンクポインタ、および標準の呼び出し規約に役立つ命令を明示的にサポートしています。しかし、独自の呼び出し規約を考案して実装することはできます。