« 「天文屋のためのマイコン入門」サブルーチンの導入 | トップページ | 「天文屋のためのマイコン入門」PICマイコンのコンフィグレーション »

2014年6月15日 (日)

「天文屋のためのマイコン入門」サブルーチンについて考える

今日は、サブルーチンについて、もう少し考えて見たいと思います。

まず、最初に問いです。

サブルーチンの処理の中で別のサブルーチンを呼べるか?

1406151

この問いに私が答えを言うのは簡単です。でも、せっかくなので、サブルーチンの動作の仕組みを考えながら、上記問いの答えを考えてみたいと思います。

まず、サブルーチンコール命令を良く見てみます。

CALL ラベル

この命令によって、ラベルの番地にジャンプします。しかし、似たような命令がありました。

GOTO ラベル

これも、ラベルの番地にジャンプします。CALLもGOTOも動作が同じように見えます。どこが違うのでしょうか? CALLをGOTOに変えたらプログラムは動くでしょうか? 当然ですが、動きません。では違いはどこにあるのでしょうか?

その違いの鍵はサブルーチンから戻るRETURN命令にあります。

RETURN

この命令、番地の指定は一切ありません。それなのになぜ、元の番地に戻れるのでしょうか?

さらに、次のような場合を考えてみてください。メイン処理の中で、同じサブルーチンを2回呼ぶとします。

1406152

図を見れば分かるように、2回RETURN命令が実行されますが、まったく同じ番地の同じRETURN命令なのに、1回目と2回目で戻る番地が違うのです。

これはちょっと考えると不思議です。RETURN命令はどうして戻り先が分かるのか?

勘のいい人ならもうわかると思いますが、答えは、

CALL命令が戻り番地をどこかに保存しておいて、RETURN命令はそれを参照している。

その通りです。CALL命令は戻り番地はたやすく分かります。なぜなら、自分自身の番地+1が戻り番地だからです。それをどこかに保存してからラベルの番地へジャンプします。

CALL命令=戻り番地の保存+GOTO命令

と考えられます。ここで最初の問いに戻ります。

サブルーチンの処理の中で別のサブルーチンを呼べるか?

答えはNOということになります。理由はこうです。戻り番地の保存先がどこかにあるとします。それをBUFと呼ぶことにします。

1 MAINからSUB1をコールするとき、MAINの戻り番地がBUFに保存される
2 SUB1からSUB2をコールするとき、SUB1の戻り番地がBUFに保存される

この時点で、MAINの戻り番地が上書きされますので、SUB1からMAINに戻ることはできなくなります。

1406153

ただし、これは戻り番地を保存する場所が一つしかないとした場合です。もし2つあるなら答えはYESになります。

1406154

実は、保存する場所は8つあります。したがって、サブルーチンの中でサブルーチンを呼ぶことをネストするといいますが、ネストレベル8まで許されるということです。

9回目ネストすると、最初の保存場所が上書きされるので、もう最初の位置に戻ることはできません。

ここで勘違いして欲しくないのは、サブルーチンが8回までしかコールできないと言っているのではないです。また、サブルーチンは8個までしか定義できないと言っているのでもありません。

サブルーチンは何個でも定義できますし、何回でも呼ぶことができます。ただ、サブルーチンの中から別のサブルーチンを呼ぶネスト構造が8レベルまでということです。ロシアのマトリョーシカ人形は8個までということです。ここは勘違いしないように注意してください。

中級者向け補足(ここの説明がわからなかったら、それはそれでいいです)

ここで言うネストレベルとは、実際ににCALL命令が実行された場合の問題です。単にプログラム中にCALL命令があるだけでは判断できません。もし、条件判定などでこのCALL命令が実行されないなら、これはネストレベルの中に含まれません。このように実行時にきまる問題を動的な問題といいます。(反対は静的な問題)ネストレベルは動的な問題です。

|

« 「天文屋のためのマイコン入門」サブルーチンの導入 | トップページ | 「天文屋のためのマイコン入門」PICマイコンのコンフィグレーション »

コメント

コメントを書く



(ウェブ上には掲載しません)




« 「天文屋のためのマイコン入門」サブルーチンの導入 | トップページ | 「天文屋のためのマイコン入門」PICマイコンのコンフィグレーション »