本当に初心者の人に捧げるコンピューター入門


補足 その5−C

Z−80の命令の簡単な解説(2)

 前のページから続いています。


入出力命令



 この命令は外部入出力装置とデータをやりとりするための命令です。
 外部入出力装置には通常I/Oポートというアドレスのような物が割り当てられています(Z−80では256個あります)それを利用してCPUは様々な機器と通信を行うわけです。

命令 意味
IN I/Oポートからレジスタにデータを読み込む。
INI,INIR 後方に向かうブロック入力命令。メモリーの一定範囲に一気にデータを読み込みたいときに使う。
IND,INDR 前方に向かうブロック入力命令。
OUT I/Oポートにデータを送り出す。
OUTI,OTIR 後方に向かうブロック出力命令。メモリーの一定範囲のデータを一気に出力したいときに使う。
OUTD,OUTR 前方に向かうブロック出力命令。


待避・復帰命令



 この命令はレジスタに入っているデータを一時的にどこかに「置いておく」ときに使います。

命令 意味
PUSH レジスタのデータをメモリーに置いておく(待避する)
POP 置いておいた(待避していた)データを元に戻す(復帰する)

 レジスタの数は非常に少ないので、たくさんの数値を使って計算していると、空いたレジスタはすぐなくなってしまいます。そういう場合当然ながらレジスタの中身を一時的にどこかに置いておく必要があります。
 もちろん自分でメモリーの場所を決めてそこにデータをコピーしておいてもいいのですが、いちいちそんなことをするのは面倒です。この命令を使うと、CPUが適当な場所を決めてデータを保管してくれます。
 では保管したデータはどうやって元に戻すのでしょう?これは以下のような調子です
 PUSH  BC      ここでBCレジスタのデータが保管される(1)
 ...
 PUSH  BC      ここでまたBCレジスタのデータが保管される(2)
 ...
 POP   BC     (2)で保管したデータが BCレジスタに復元される
 ...
 POP   BC     (1)で保管したデータが BCレジスタに復元される
 POPしたときには一番最近にPUSHしたデータがまず返ってきます。
 もう一度POPすれば、その一つ前にPUSHしたデータが・・・というようにとにかく一番最後にPUSHしたデータが一番最初に返ってくるわけです。

  • この仕組みを実現するアルゴリズムをスタックといって、数あるアルゴリズムの中でも非常に強力で応用範囲の広い方法です。これを使うと前の補足で出した左手の法則の効かない迷路の問題が、実にエレガントに解決できます。

サブルーチンコール



 CALL命令は現在のレジスタ内容と次の命令のアドレスをPUSHしてから指定したアドレスにジャンプする命令です。

命令 意味
CALL サブルーチンを呼び出す
RET サブルーチンから戻る

 RET命令はPUSHしてあったプログラムカウンタをPOPしてそのアドレスにジャンプして、更に保管してあったレジスタ内容を復帰させる命令です。
 これがどういう動作をするかというと、例えば以下のようにプログラムがあった場合、

1000    CALL    2000
1003    何かの処理
...
...
1500    CALL    2000
1503    何かの処理
...

2000    いろいろな処理
...
2500    RET
  1. 1000番地に来たら現在のレジスタの内容と次の命令の番地(この場合は1003番地)を保存して2000番地に飛ぶ
  2. 2000番地以降の処理をする
  3. RETが来たら1003番地にジャンプしてレジスタの内容を復元する
  4. 1500番地に来たら現在のレジスタの内容と次の命令の番地(この場合は1503番地)を保存して2000番地に飛ぶ
  5. 2000番地以降の処理をする
  6. RETが来たら1503番地にジャンプしてレジスタの内容を復元する
  7. ・・・
というような処理をします。
 これが何に使えるかというとサブルーチンを実現するためです。サブルーチンとは、同じような処理があちこちで発生した場合、それを1カ所にまとめることができるという機能ですが、非常に重要な機能なので高級言語のところで
もっと詳しく説明します。

 ちなみに、ジャンプするときにJP命令同様に条件付きもできます。


割り込み



 ちゃんとしたCPUには割り込みという機能がついています。これは外部からの信号が来たときに特定の処理を行わせる機能です。
 これに関しても
後でもっと詳しく説明しますから、そんなものかと思っていてください。

命令 意味
DI 割り込みを不可にする。
EI 割り込みを可能にする。
IM 割り込みモードを設定する。
RETI 割り込み処理ルーチンから戻る
RETN ノンマスカラブル割り込み処理ルーチンから戻る


その他



 これ以外にも以下のような機能があります。

命令 意味
HALT CPU停止
RST リスタート命令*(00h,08h,10h...38hのどれかのアドレスにジャンプする)
NOP 何もしない**
EX 裏レジスタとチェンジ***Z−80のスペシャル機能。
EXX


リスタート

 コンピューターは電源を入れるととりあえず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がどの程度のものかというと・・・

加減乗除 絶対値
剰余 四捨五入
平方根 2の累乗
三角関数(sin cos tan)逆三角関数(arctan)
対数

の計算ができるぐらいです。関数電卓だったらもっと機能がありますね。名前ほどにはすごくないようです。
 ですからもっと複雑な計算がしたければ結局その計算をするためのプログラムを作らなければなりません。

 結局昔も今も、ちょっとしたことをするにも大量のプログラムを書かなければならないという点は同じなのです。



前へ 目次へ 次へ