マイクロプロセッサにおけるスタックの役割は何ですか?
10 に答える
最下位レベルでは、スタックは特定の命令がデータを保存または取得する場所であり、割り込みが発生したときにデータが保存される場所です。マイクロプロセッサはさまざまですが、スタック固有の命令には 5 つの一般的なタイプがあります。
- PUSH - データをスタックに入れる
- POP (または PULL) - スタックからデータを「削除」する
- CALL - サブルーチンにジャンプし、戻りアドレスをスタックに置く
- RETURN - プログラム カウンターにスタック トップをロードしてサブルーチンから戻る
- INT (または SWI) - ソフトウェア割り込み。特殊な CALL
(外部デバイスによる) プロセッサ割り込みが発生すると、CPU は現在のプログラム カウンタと (通常は) フラグ レジスタをスタックに保存し、処理サブルーチンにジャンプします。これにより、処理サブルーチンは割り込みを処理し、現在の状態を保持して CPU が行っていた処理に戻ることができます。
マイクロプロセッサは一度に 1 つのスタックしかアクティブにできませんが、オペレーティング システムは複数のスタックがあるように見せることができます。少なくとも OS 用に 1 つ、プロセスごとに 1 つ、スレッドごとに 1 つ。実際、スレッド自体が複数のスタックを実装している場合があります。
より高いレベルでは、スレッドを実装するために使用される言語が何であれ、関数呼び出しパラメーター、ローカル変数、および関数呼び出しの戻り値を格納するために、独自の目的でスタックを使用することがよくあります (ここで大まかに言えば、言語の低レベルを参照してください)。特定の詳細についてはドキュメンテーション)。
以上でスタックについてのボトムアップの説明を終わります。
コンピューティングの初期の頃は、サブルーチンの呼び出しは、各サブルーチンにメモリRAMのワードを持たせて、どこから呼び出されたかを示すことによって処理されていました。サブルーチンを呼び出すには、次のようにします。
foo_returnを#LABEL_123でロードします goto foo #LABEL_123: ...fooから戻った後に実行するコード foo: ...何かをする goto foo_return
このパターンは、発信者に差出人住所をレジスタに配置させ、ルーチンにエントリの「差出人」スポットに格納させることによって最適化される可能性があります。このパターンは機能しましたが、いくつかの問題がありました。一般的にメモリを浪費するだけでなく、再帰的または再入可能なコードを処理する手段もありませんでした。スタックを追加すると、呼び出し元が以前のアドレスを邪魔することなく「適切な場所にリターンアドレスを保存する」と言うだけで、呼び出された関数が「そうでない最新の呼び出し元に戻る」と言うだけで、コードを簡略化できます。まだに戻されました」。これにより、再入可能なコードの開発が可能になり、実際に発生する可能性のある最も深いネストされた関数呼び出しのチェーンを処理するのに十分なリターンアドレスを格納するだけで済みました。
マイクロプロセッサに依存します。一般に、その役割はローカル変数と関数のパラメーターを保持することです。
実際にはマイクロプロセッサではなく、中央メモリにあります。
http://www.hobbyprojects.com/microprocessor_systems/images/stack.gif
スタックはデータの一時的なストアです。
CPUは、他のデータを処理しているときに、重要なデータをスタックにプッシュする場合があります。
そのタスクが完了すると、保存されたデータをスタックからプルします。
それはプレートの山のようです。一番下のプレートは、スタックにプッシュされたデータの最初のビットです。トッププレートは最後にプッシュされるデータです。上部プレートが最初に引っ張られ、下部プレートが最後に引っ張られるデータです。これは後入れ先出しスタックです。
図では、Xが最初にプッシュされ、次にY、最後にAがプッシュされます。CPUは他のデータを処理するために停止します。そのタスクが完了すると、保存されたデータをプルするために戻ります。最初にAが引っ張られ、次にY、最後にXが引っ張られます。
データをプッシュするための命令はPHAです。アキュムレータ内のデータのみをスタックにプッシュできます。他のデータは、最初にアキュムレータに転送された場合にプッシュできます。
スタックからデータをプルするための命令はPLAです。スタック上のデータはアキュムレータに転送されます。
6502スタックは256バイトで構成され、ページ1、アドレス256〜511を占有します。
スタックは、LIFO (後入れ先出し) バッファーの実装です。FIFO (First In - First Out) はキューとも呼ばれます。しかし、LIFOに戻ります。
x86 アーキテクチャのスタックにより、ソフトウェア設計者は、RISC プロセッサに見られるリターン アドレス レジスタや割り込みリターン アドレス レジスタなどの奇妙なものを省くことができます。すべてがスタックに常駐できるため、コール/リターン、パラメーター/ローカル変数、および割り込み/割り込みリターンを処理する単一の標準化された統一された方法があります。個別のスタックでメソッドを使用すると、マルチスレッドの実装が簡素化されます。
対照的に、RISC はスタックのようなバッファを使用しますが、関連情報の重要な部分を別の場所に保持します。RISC の「スタック」の方が高速かもしれませんが (確実ではありません)、x86 のスタックよりも理解しにくいことは間違いありません。
これらの回答の一部に追加すると、PIC ラインなどの一部のローエンド マイクロにはハードウェアコールスタックがあり、これはハードウェアのように動的に割り当てることができないことを意味します。
これが意味することは、スタックを使い果たす前に非常に多くの関数呼び出ししか深くできないということです。これはもちろんソフトウェアにも当てはまりますが、多くの場合、ハードウェアベースのスタックは非常に制限されている可能性があり、関数呼び出しを「フラット化」するためにプログラムを再考する必要がある場合があります。
実はスタックはプロセッサの用語ではなく、言語のルーチン呼び出しに使われています。ルーチンは、スタックを使用してパラメーターを取得し、ローカル変数を保存し、他のルーチンを呼び出すこともできます。