公開日:2007年9月26日
独立行政法人情報処理推進機構
セキュリティセンター
本ページの情報は2007年9月時点のものです。
記載の資料は資料公開当時のもので、現在は公開されていないものも含みます。
スタックは、それまでの作業を「棚上げ」し、のちにそれを再開できるようにする仕組みである。スタックはメモリの中の特定の領域を占め、「スタックポインタ」というレジスタを通じてアクセスされる。スタックに保存されるデータは、領域の中の大きなアドレスから小さなアドレスへ向かって順に置かれてゆく。スタックポインタは、スタックに置かれたデータの先頭のアドレスを保持している。
スタックを操作する機械命令に、PUSHとPOPがある。
PUSH命令は、スタックに値を積む命令である。PUSH命令が実行されると、保存される値の大きさのぶんだけスタックポインタが減らされたのち、スタックポインタが指す箇所のメモリに値が保存される。
POP命令は、スタックから値を回収する命令である。POP命令が実行されると、スタック内容先頭の値がどれかのレジスタへ転送されるとともに、その値の大きさのぶんだけスタックポインタが増やされる。
関数呼び出しも「ジャンプ」の一種であるが、単純なジャンプとは異なるところがある。すなわち、呼び出された関数における処理が済んだら、呼び出しの直前に実行していた命令の流れの続きに戻る必要がある。プロセッサには関数呼び出しのための命令と復帰のための命令が用意されているが、これらは大抵「スタック」という仕組みと共に動作するよう作られている。
(注: コンパイラによっては、スタックを用いずに関数呼び出しを実現しているものもある。)
関数呼び出しの命令(CALL命令)は、それまでの命令カウンタの値をスタックに積んでから(PUSHと同様の動作)、目的の関数の先頭を指すよう命令カウンタを書き換える。
関数から呼び出し元に復帰する命令(RET命令)は、スタックからアドレス値を回収し(POPと同様の動作)、そのアドレス値を命令カウンタへ転送する。
スタックは、関数の呼び出しと復帰の際の命令実行順序をコントロールするのみならず、関数への引数受け渡しや関数内のローカル変数のための領域としても用いられる。関数呼び出しの際の引数受け渡しは、呼び出し側で値(単数もしくは複数)をスタックへ積む(PUSH)ことで実現される。呼び出された関数のローカル変数領域もスタックの上に確保される。