スタック操作

「スタック」はスタックポインタの説明で簡単にふれたとおり、データ用メモリを使ってプログラムの「入れ子構造」を実現するものです。詳しい説明はこちらを見ていただくとして、DeMでは「プッシュ」操作と「ポップ」操作を実装しています。

言葉だけだと分かりずらいので例で説明します。今スタック領域のメモリ上に右図のようにデータが並んでおり、スタックが形成されているとします。スタックポインタ(SP)がスタックの頂上(「スタックトップ」といいます)を指し示しています。

プッシュ操作はレジスタの内容をスタックに「押し込む」操作で、スタックポインタ(SP)の内容をまず減らしてーすなわち空きを作ってーそのアドレスのメモリにレジスタの内容を書きだすというものです。レジスタの値を「一時退避」するのによく使います。

ポップ操作はスタックからデータを「飛び出させ」てレジスタに入れるという操作で、SPの内容で指しているメモリを読み込んでレジスタに入れた後SPを増加させるー空きをつぶすーというものです。「一時退避」したレジスタの内容を元に戻すのによく使います。

なお、SPの増減は4バイト単位で行われます。操作対象のレジスタの長さが4バイト=10進8桁だからです。また、図からわかるとおりSPは10進2桁の長さしかなく、上位に「20」を付加してメモリアドレスにします。つまりプッシュまたはポップをいくら繰り返しても2000から2099の間に収まることになります。

DeMではアキュムレータ(A)と汎用レジスタで命令を使い分けます。

Operation Mnemonic inCode Opr2 Opr3 Opr4 Opr5 #bytes Opcode Ie Cy Cd
A <- (SP) then SP <- SP + 4 POPA 1 36
SP <- SP – 4 then (SP) <- A PUSHA 1 37
Rd <- (SP) then SP <- SP + 4 POP Rd 2 34 8R
SP <- SP – 4 then (SP) <- Rs PUSH Rs 2 34 9R

汎用レジスタの”PUSH”、”POP”については、Opcode欄の「R」にあたるところにレジスタ番号0~9を入れてください。Rsとは転送元レジスタ(Source Register)のこと、Rdとは転送先レジスタ(Destination Register)のことです。

コーディング例

Addr Data Label Opcode Operand Comment
0000 37 start: PUSHA Aの内容をスタックにプッシュする
0001 34 80 POP R0 スタックからポップしてR0に入れる
0003 34 98 PUSH R8 R8の内容をスタックにプッシュする
0005 36 POPA スタックからポップしてAに入れる

補足

  • SPはリセットあるいは電源オン時に00に初期化されますが、それ以外ではSPを初期化、設定することはできません(命令がありません)。
  • 簡略化のためスタックのオーバーフローとアンダーフローの検出や対処などはサポートしていません。スタックを溢れさせないよう使ってください。
  • ここでいう転送とは内容をコピーすることで、転送元にはデータが残ります。
  • この命令はステータスレジスタ(SR)を変化させません。