「スタック」はスタックポインタの説明で簡単にふれたとおり、データ用メモリを使ってプログラムの「入れ子構造」を実現するものです。詳しい説明はこちらを見ていただくとして、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)を変化させません。