補足 その5−C Z−80の命令の簡単な解説(2) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
前のページから続いています。入出力命令この命令は外部入出力装置とデータをやりとりするための命令です。 外部入出力装置には通常I/Oポートというアドレスのような物が割り当てられています(Z−80では256個あります)それを利用してCPUは様々な機器と通信を行うわけです。
待避・復帰命令この命令はレジスタに入っているデータを一時的にどこかに「置いておく」ときに使います。
レジスタの数は非常に少ないので、たくさんの数値を使って計算していると、空いたレジスタはすぐなくなってしまいます。そういう場合当然ながらレジスタの中身を一時的にどこかに置いておく必要があります。 もちろん自分でメモリーの場所を決めてそこにデータをコピーしておいてもいいのですが、いちいちそんなことをするのは面倒です。この命令を使うと、CPUが適当な場所を決めてデータを保管してくれます。 では保管したデータはどうやって元に戻すのでしょう?これは以下のような調子です PUSH BC ここでBCレジスタのデータが保管される(1) ... PUSH BC ここでまたBCレジスタのデータが保管される(2) ... POP BC (2)で保管したデータが BCレジスタに復元される ... POP BC (1)で保管したデータが BCレジスタに復元されるPOPしたときには一番最近にPUSHしたデータがまず返ってきます。 もう一度POPすれば、その一つ前にPUSHしたデータが・・・というようにとにかく一番最後にPUSHしたデータが一番最初に返ってくるわけです。
サブルーチンコールCALL命令は現在のレジスタ内容と次の命令のアドレスをPUSHしてから指定したアドレスにジャンプする命令です。
RET命令はPUSHしてあったプログラムカウンタをPOPしてそのアドレスにジャンプして、更に保管してあったレジスタ内容を復帰させる命令です。 これがどういう動作をするかというと、例えば以下のようにプログラムがあった場合、 1000 CALL 2000 1003 何かの処理 ... ... 1500 CALL 2000 1503 何かの処理 ... 2000 いろいろな処理 ... 2500 RET
これが何に使えるかというとサブルーチンを実現するためです。サブルーチンとは、同じような処理があちこちで発生した場合、それを1カ所にまとめることができるという機能ですが、非常に重要な機能なので高級言語のところでもっと詳しく説明します。 ちなみに、ジャンプするときにJP命令同様に条件付きもできます。 割り込みちゃんとしたCPUには割り込みという機能がついています。これは外部からの信号が来たときに特定の処理を行わせる機能です。 これに関しても後でもっと詳しく説明しますから、そんなものかと思っていてください。
その他これ以外にも以下のような機能があります。
*リスタートコンピューターは電源を入れるととりあえず0番地にある命令からプログラムを実行し始めます。要するにこの命令はもう一度電源を入れた所からやり直せ!という命令です。もっと平たくいえば、コンピューターを再起動させる命令です。 ** 何もしないことに何の意味が?NOPという何もしない命令に何の意味があるのでしょう?今でこそあまり深い意味はなくなってしまったのですがこの当時はこれがなかったら大変なことになっていたのです。 本文の偽機械語のプログラムをもう一度見てください。あっちこっちにジャンプ命令がありますね。 1136 SUB 261 1 後は西しか残らないので 1139 JP 1141 左に道があった場合、左に進む 1141 CMP [261] 0 左に隣接している場所が道だった場合は 1144 JNZ 1154 (違った場合は次) 1146 LD 231 [260] 左を向いて 1149 LD 230 [261] 左に行く上はその一部の再録ですが、1139と書かれた行をよく見てください。これは1141番地にジャンプせよという命令なのですが・・・よく見ると1141番地というのはこのプログラムの単なる次の行です!要するにこの行は間違いではないが無駄な存在なのです。 ではそんな物削ればいいと思うでしょう?ところがこの行を削ってしまうと大変なことが起こるのです。 例えば1144番地も"JNZ 1154"とありますが、1139番地の行を削ると全体が2アドレス分だけずれてしまうので、これは"JNZ 1152"と書き換えなければいけません。以降のジャンプ命令で1139番地以降の番地を指している命令はすべて書き換えなければならないのです! この程度の短い(?!)プログラムならそれも可能です(筆者はそれさえする気が起きなかったので、ほったらかしにしてますが)しかしもっと長いプログラムだったらと考えるとぞっとしませんか?そのうえ間違いがこれで最後という保証さえないのです! 実はNOP命令の大きな意義はここにあるのです。すなわち、この例であれば1139番地からNOPを二つ入れておけば、ジャンプの書き換えは不要です。 またあらかじめプログラムのあちこちにNOP命令を十個づつぐらい挟んでおけば、途中でちょっと行の挿入があっても修正する範囲はそのNOPの所までで済むわけです。 *** 裏レジスタZ−80では裏レジスタというレジスタセットがもう一組内蔵されていました。これは上記のEX命令で表と入れ替えることができました(今まで表だったレジスタは裏になるわけです)これを使うとPUSHやPOPでデータを待避するのに比べて非常に高速に待避・復帰ができます。もちろん表裏が入れ替わるだけですから何度もPUSHするようなことはできませんが、ちょっと待避するだけなら非常に効果的でした(当然プログラムを組んでいくうちに今表裏のどっちだったか忘れてしまうというオチはありましたが) この命令はZ−80特有で、ペンティアムなどにはありません。 ペンティアムだとどうなっている?さて今までの例はZ−80という太古のCPUの話でした。では1998年3月現在に比較的最新鋭のCPUであるペンティアムではどのぐらいすごくなっているのでしょう? 詳しくは書けませんが以下のような感じです。 ● 32ビット演算が可能Z−80では一度に8ビット、すなわち0〜255までの計算しかできませんでしたが、ペンティアムでは32ビット(0〜4,294,967,296)までを扱うことができます。● かけ算わり算ができるZ−80では足し算と引き算しかできませんでしたが、かけ算わり算ぐらいもできるようになっています。● マルチタスク用の命令の追加最も大きな違いは、この命令群があることです。ウインドウズなどを使っていると、複数のプログラムを同時に動かすことができますね。こういうことが楽に安全にできるような仕組みがCPUにあらかじめ備わっているのです。(この辺の所も後のOSのところで詳しく説明します) ● 浮動小数点演算ができるまた整数以外の浮動小数点数も計算できます。といってもCPUが直接浮動小数点を扱えるわけではなく、数値演算コプロセッサという浮動小数点専用のCPU(昔は別売りでした)がもう一個内蔵されていて、それを呼び出すわけです。 ではその専用CPUがどの程度のものかというと・・・
の計算ができるぐらいです。関数電卓だったらもっと機能がありますね。名前ほどにはすごくないようです。 ですからもっと複雑な計算がしたければ結局その計算をするためのプログラムを作らなければなりません。 結局昔も今も、ちょっとしたことをするにも大量のプログラムを書かなければならないという点は同じなのです。 |