スタックレジスタ(スタックポインタとも呼ばれる)は、コールスタックを追跡するためのコンピュータの中央処理装置(CPU)レジスタです。アキュムレータベースのアーキテクチャのマシンでは、これは専用レジスタである場合があります。複数の汎用レジスタを備えたマシンでは、 IBM System/360からz/ArchitectureアーキテクチャやRISCアーキテクチャのように、慣例によって予約されたレジスタである場合もあれば、PDP-11、VAX、Intel x86アーキテクチャのように、プロシージャ呼び出し命令とリターン命令がハードワイヤリングされて使用するレジスタである場合もあります。Data General Eclipseなどの一部の設計では、専用レジスタはなかったものの、この機能のために予約されたハードウェアメモリアドレスを使用していました。
1960年代後半以前のマシン(PDP-8やHP 2100など)には、再帰をサポートするコンパイラがありませんでした。これらのマシンのサブルーチン命令は通常、現在の位置をジャンプアドレスに保存し、次にプログラムカウンタを次のアドレスに設定します。[ 1 ]サブルーチンコードセクションごとにリターン位置が1つしかないため、スタックを維持するよりも簡単ですが、プログラマがかなりの労力をかけなければ再帰はできません。
スタックマシンには2つ以上のスタックレジスタが存在する場合があります。そのうちの1つはコールスタックを追跡し、他のレジスタは他のスタックを追跡します。
より単純なプロセッサでは、スタックポインタを通常のハードウェアレジスタに格納し、算術論理演算ユニット(ALU)を使用してその値を操作します。スタックにアイテムをプッシュしたり、スタックからアイテムをポップしたりする命令を持つプロセッサでは、これらの命令は複数のハードワイヤードCPUサイクルまたはマイクロ命令で実行されるか、複数のマイクロオペレーションに変換され、スタックポインタを個別に加算/減算し、メモリへのロード/ストアを実行します。[ 2 ]
この種の新しいプロセッサには、スタック操作を最適化するための専用のスタック エンジンが搭載されています。Pentium M は、スタック エンジンを導入した最初の x86 プロセッサでした。その実装では、スタック ポインタは 2 つのレジスタに分割されています。1 つは 32 ビット レジスタであるESP O 、もう1 つはスタック操作によって直接更新される 8 ビットのデルタ値であるESP dです。PUSH、POP、CALL、および RET オペコードは、ESP dレジスタと直接連携します。ESP dがオーバーフローに近い場合、または ESP レジスタが他の命令から参照されている場合 (ESP d ≠ 0 の場合)、同期マイクロ オペが挿入され、ALU を使用してESP Oを更新し、ESP d を0 にリセットします。この設計は、ESP O が64 ビットに拡張されたものの、後の Intel プロセッサでもほとんど変更されていません。 [ 3 ]
Intel のスタック エンジンと同様のスタック エンジンがAMD K8マイクロ アーキテクチャにも採用されました。Bulldozer では同期マイクロ オペレーションの必要性がなくなりましたが、スタック エンジンの内部設計は不明です。[ 3 ]
ほとんどのコンピュータは、戻りアドレスをスタック、レジスタのいずれか、またはプロシージャの最初のワードに保存します(この場合、プロシージャの最初の実行命令は2番目のワードに格納する必要があります)。後者の方法を使用する場合、プロシージャからの戻りは、プロシージャの最初のワードに含まれるアドレスを持つメモリ位置へのジャンプです。(xiv+294+4ページ)