[PP0906] 10. コールとリターン
今回はサブルーチンを呼出すための仕組みを追加します。サブルーチンというのは、決まった仕事をするための小さなプログラムのことで、C 言語の関数に相当します。というより、C 言語の関数も、一種のサブルーチンとして実現されています。
| 命令 | ニーモニック | 命令長 | 意味 |
|---|---|---|---|
| 17 | CALL | 2 | サブルーチンを呼出す |
| 18 | RET | 1 | サブルーチンから呼出し元に戻る |
それではいつものように、CALL と RET 命令を使ったプログラムを作ってみましょう。
int program[] =
{
LXI, 0x10000,
MOVSX,
{
LXI, 0x10000,
MOVSX,
LI, 123,
OUT,
CALL, 0x100,
LI, 456,
OUT,
-1,
};
int sub1[] =
{
LI, 789,
OUT,
RET
};
08. ジャンプで紹介したように、呼出し先のプログラムは別の配列に収めています。この配列 sub1 がサブルーチンに相当します。これを、main 関数のはじめで、
memcpy(&memory[0x100], sub1, sizeof sub1);
として、メモリにロードするようにしてください。実行結果は次のようになることを想定しています。
0x0000007b(123)
0x00000315(789)
0x000001c8(456)
0x00000315(789)
0x000001c8(456)
それでは、命令を追加していきたいと思います。
case CALL:
eaddr = memory[pc];
pc = pc + 1;
sp = sp - 1;
memory[sp] = pc;
pc = eaddr;
break;
case RET:
pc = memory[sp];
sp = sp + 1;
break;
eaddr = memory[pc];
pc = pc + 1;
sp = sp - 1;
memory[sp] = pc;
pc = eaddr;
break;
case RET:
pc = memory[sp];
sp = sp + 1;
break;
CALL 命令では、まず始めに、オペランドである 2 ワード目を読み込んで実効アドレスとし、PC を 1 進めています。この時点で、PC は次の命令のアドレスを保持しているはずです。そして、その PC の値をスタックに退避しています。最後に、実行アドレスを PC に代入することで、サブルーチンにジャンプしています。
RET 命令では、スタックから戻り先アドレス(CALL 命令の次の命令を指しているはず)を取り出し、そのアドレスにジャンプしています。ここで、CALL と RET、あるいは PUSH と POP がうまく対応していないと、つじつまが合わなくなってしまうので要注意です。
この記事のトラックバックURL:
http://www.kijineko.co.jp/trackback/525
ブックナビゲーション
- 技術情報
- 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 - 初級者向け擬似プロセッサ
- 象の卵を探して...
- 車輪の再発明
- 過去の情報

