このページをはてなブックマークに追加このページを含むはてなブックマーク このページをlivedoor クリップに追加このページを含むlivedoor クリップ

目次

スタック

・後入れ先出し型(一番後に入れるものから先に取り出す)のデータ構造をスタックと呼ぶ。 

SP(Stack Pointer:スタックポインタ)とはスタック最上段のアドレスを保持している16ビットのレジスタである。あくまでスタックの中身ではなく、スタックのどの部分を今処理中かということを指し示すポインタである。

PRは次の処理に対応するアドレスを保持している16ビットのレジスタである。

COMET兇離好織奪

・プログラム起動時に十分な容量のスタック領域をメモリに確保する。

・スタック領域の最後のアドレスに1を加算した値をSPに設定する。

スタック操作命令

PUSH

PUSH アドレス [,GRx]

スタック←アドレス+GRx

あるいは

SP←SP-1
M(SP)←アドレス+GRx

POP

POP GRn

GRn←スタック

あるいは

GRn←M(SP)
SP←SP+1

サブルーチン

CALL(CALL subroutine:コール)

CALL アドレス [,GRx]

アドレス+GRx番地を呼ぶ

あるいは

SP←SP-1
M(SP)←PR
PR←アドレス+GRx

 F式表記を見てもらえればわかるが、CALL命令で副プログラムに飛んだとき、スタックの中にCALL命令の次のアドレス(普通はRET命令がある)が代入される。つまり、副プログラムから復帰したときどこにジャンプしたらよいかという情報を残すために、スタックにそのアドレスが代入されるのである。

RET(RETurn from subroutine:リターン)

RET

主プログラムに復帰する

あるいは

PR←M(SP)
SP←SP+1

主プログラムと副プログラムの汎用レジスタ

 COMET兇任蓮GR0からGR7までの8個の汎用レジスタしか使用できない。つまり複雑なプログラムでは汎用レジスタが明らかに足りなくなる。通常、大きなプログラムは複数の副プログラム(サブルーチン)に分割して作られる。副プログラムので、主プログラムが使っている汎用レジスタをそのまま使ってしまうと、副プログラムが終わって主プログラムに戻ってから前に汎用レジスタに代入したものを使おうと思っても、もうデータは上書きされてしまいなくなってしまう。
 この問題を解決するためには、まず主プログラムで使用した汎用レジスタの値を一旦スタックにすべて記録しておき、その後で副プログラムにジャンプさせればよい。そうすれば副プログラムで汎用プログラムを思う存分使うことができ、リターンで主プログラムに戻ってきたらスタックから汎用レジスタにまた戻してやればよいのだ。
 ちなみに、PUSH命令で一番最後にスタックに入れたものからPOP命令で取り出されることを忘れてはならない。例えば、PUSH命令でGR0,…,GR7の順でレジスタからスタックへ退避させた場合、POP命令でGR7,…,GR0の順でスタックからレジスタに戻してやる。

例:トレースしてみればわかる。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
SAMPLE    START     
          LAD       GR1,#1111
          LAD       GR2,#2222
          LAD       GR3,#3333
          CALL      SUBF
          RET       
          END       
SUBF      START     
          PUSH      0,GR1
          PUSH      0,GR2
          PUSH      0,GR3
          LAD       GR1,#AAAA
          LAD       GR2,#BBBB
          LAD       GR3,#CCCC
          POP       GR3
          POP       GR2
          POP       GR1
          RET       
          END       

参考文献

  • 『情報処理試験 CASLII 〜CASLIIの講義と実習〜 [第2版]』