[PP0906] 09. スタック操作
プログラムを実行する上で、非常に重要なデータ構造がスタックです。多くのプロセッサでは、スタックを利用するためのハードウェア的な仕組みが設けられています。スタックは、レジスタの値を一時的に退避したり、サブルーチンを呼出すときに戻り先のアドレスを退避する目的に使われます。
| 命令 | ニーモニック | 命令長 | 意味 |
|---|---|---|---|
| 13 | PUSH | 1 | アキュムレータをスタックに積む |
| 14 | POP | 1 | スタックから値を取り出し、アキュムレータに格納する |
| 15 | PUSHX | 1 | インデックスレジスタをスタックに積む |
| 16 | POPX | 1 | スタックから値を取り出し、インデックスレジスタに格納する |
それでは、スタック操作を行うための簡単なプログラムを書いてみましょう。今回は PUSHX と POPX の使用例は割愛し、PUSH と POP だけを使っています。PUSHX と POPX については、動作確認も兼ねて、各自でプログラムを作ってみてください。
{
LXI, 0x10000,
MOVSX,
LI, 123,
LXI, 456,
PUSH,
MOVAX,
OUT,
POP,
OUT,
-1
};
上のプログラムで、最初の二つの命令(LXI,0x10000 と MOVSX)は、SP の初期化のためのものです。PP0906 では、PC 以外のレジスタは起動時の値が不定になります。SP も例外ではありません。したがって、SP を初期化する必要があるわけです。しかし、SP に直接即値をロードする命令はありませんので、いったんインデックスレジスタを介して初期値を設定することになります。
次に、アキュムレータとインデックスレジスタのそれぞれに即値をロードし、インデックスレジスタ → アキュムレータの順に値を出力しようとしています。インデックスレジスタの値を直接出力する命令はありませんので、アキュムレータを介さなければならないわけですが、それではアキュムレータの値を破壊してしまいます。そこで、PUSH 命令を使って、いったんアキュムレータの値をスタックに退避しています。
それから、インデックスレジスタの値をアキュムレータに転送し、出力しています。次に、アキュムレータの元の値をスタックから取り出し、出力しています。
スタックは、通常上位のアドレスから下位のアドレスへ向かって使用されます。そのため、SP の初期値は、配列 memory の要素数であり、最大のアドレス + 1 の値である 0x10000 を使用しています。スタックに値を積むときは、まず SP を 1 減じてから、その値をアドレスとして、メモリにレジスタの値を書き込みます。逆に、スタックから値を取り出すときは、その時点の SP の値をアドレスとして、メモリから値を読み取り、その後に SP に 1 を加えることになります。
これを踏まえた上で、各命令を作ると次のようになります。
sp = sp - 1;
memory[sp] = a;
break;
case POP:
a = memory[sp];
sp = sp + 1;
break;
case PUSHX:
sp = sp - 1;
memory[sp] = x;
break;
case POPX:
x = memory[sp];
sp = sp + 1;
break;
スタック操作は、これから現れる PP0906 の他の命令でも使用します。上のコードは、他の要素がからまない最もシンプルなものですので、スタックでつまづいた場合は、いったんここに戻って再確認するとよいでしょう。
この記事のトラックバックURL:
ブックナビゲーション
- 技術情報
- Boost C++ Libraries メモ
- C++と組込み環境
- C++サンプル集
- C++テンプレート集
- C++プログラマのためのC言語入門
- C/C++迷信集
- C99関数・マクロ・前処理スクリプト集
- C言語再入門
- C言語徹底入門
- Drupal メモ
- TOPPERS 情報
- ベターCとしてのC++
- マイコン メモ
- ライブラリ開発入門
- 分割コンパイルをきわめる
- 擬似プロセッサを作る
- PP0906 - 初級者向け擬似プロセッサ
- [PP0906] 00. 擬似プロセッサ PP0906 を作る
- [PP0906] 01. 擬似プロセッサ PP0906 の仕様
- [PP0906] 02. 主記憶と制御装置
- [PP0906] 03. 何もしないプログラム
- [PP0906] 04. 即値のロードと出力
- [PP0906] 05. レジスタ間の転送
- [PP0906] 06. ニーモニックを使う
- [PP0906] 07. ロードとストア
- [PP0906] 08. ジャンプ
- [PP0906] 09. スタック操作
- [PP0906] 10. コールとリターン
- [PP0906] 11. インクリメントとデクリメント
- [PP0906] 12. 条件分岐
- [PP0906] 13. 加算と減算
- [PP0906] 14. 不正命令例外
- [PP0906] 15. まとめ
- PP0906 - 初級者向け擬似プロセッサ
- 象の卵を探して...
- 車輪の再発明
- 過去の情報

