補足 その5−B Z−80の命令の簡単な解説(1) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
以下はZ−80にはどんな機能があるかということの解説です。 これを見てもらえば、本物の機械語でも偽機械語に比べて本質的に優れているものではないということがわかると思います。 データ転送命令レジスタ←メモリー、レジスタ←レジスタ、メモリー←レジスタ、レジスタ←値、メモリー←値といった間でデータを転送する命令です。 同じLD命令でも組み合わせごとに違った機械語が割り当てられています。
LD命令はほとんどのレジスタ・メモリーの組み合わせが可能です。例えばAレジスタにBレジスタの値をを入れろという命令は LD A B とアセンブリ表記して、機械語は78hです(AレジスタもBレジスタも場所があらかじめ分かっているので、引数は不要です) しかしほとんどとはいっても全てではありません。例えばIレジスタに値を転送したい場合は必ずAレジスタからでなければならないという決まりがあります(CPU設計上そうなっているのです) 今回の説明ではその辺の細かいところは書いてもうっとうしくなるだけなので割愛します。以下の命令の説明もそのつもりで読んでください。 *ブロック処理こういう〜I,〜D,〜IR,〜DRとかいう名前の命令は以下にも出てきますが、ブロック処理命令といって一定範囲のメモリーに同じ処理をしたいときなどに大変便利です。LDI命令は、あらかじめHLレジスタに転送元のメモリーのアドレス、DEレジスタに転送先のアドレス、BCレジスタに適当な数をセットしておくと、HLレジスタの指しているアドレスからDEレジスタの指しているアドレスにデータをコピーした後に、HLレジスタとDEレジスタのの値を+1して、BCレジスタの値を−1してくれます。 LDIR命令はBCレジスタの値が0になるまで上の動作を繰り返します。 あるメモリーのある領域から別な領域にまとめてデータをコピーしたい時に大変便利な命令です。 LDD命令はLDI命令とほぼ同じですが、HLレジスタとDEレジスタの値が−1されるところが違います。 演算命令足し算・引き算・値の比較などを行う命令です。 この命令を行うためには8ビット演算の場合は必ずAレジスタに、16ビット演算の場合はHL,IX,IYレジスタのどれかに入れておかなければなりません。
* 補数補数をとるとは、値の二進数の各桁の1,0を反対にして1を足した値を得ることです。例えば 00000001 という値の補数は 11111111 です。これに何の意味があるかというと、実はその値の+−の符号を反対にするのと同じなのです。どうしてかって?コンピューター内部で負の数はどうやって表現されていたでしょう?Xと−Xの値には実はこんな関係があったんです。 ** 10進補正これは2進化10進数というのを扱うとき使います。コンピューターの内部ではすべて2進法で表現されているため、例えば1/5という値を表現すると内部的には無限小数になってしまい、正確な値にはならないことを前に説明しました。 しかしお金の計算などをするときにはこれでは困ります。そこで考えられたのが2進化10進数です。 これは一口でいえば、16進数で書かれたは10hという値を、10進数の10であると見なして計算できるようにしてしまおうというものです。 例えば16進数で書かれた以下の足し算は正しいですね。 12h+23h=35h ところが繰り上がりさえなければ、hをはずして10進数と見なしても同じ結果になります。 12+23=35 でも実際には繰り上がりがあって下のようなことになってしまいます。 12h+29h=3Bh 12+29=41 そこで例えば3Bhという値が来たら41hになるように補正する命令を作っておけば、あたかも16進数で10進数の計算ができるように見えるわけです。 シフト・ローテート命令これはレジスタの値のビットを回転させたりシフトさせる命令です。
といっても何のことだか分からないでしょうから例を挙げてみると
よく見れば分かるとおりシフトでは数字の位置が一個ずれており、ローテートではずれて出ていった数字が反対側から回り込んできています。でもこんなことに何の意味があるのでしょう? Z−80の演算命令には足し算と引き算しかありません。しかし実用上かけ算などができなければ電卓以下です。しかしそういう命令がない以上、結局かけ算をするプログラムを作らなければなりませんが、ちょっと考えると大変そうです。 でも昔小学校でかけ算を習ったとき、下のような問題なら楽だったでしょう?。 12345 × 1011 ←掛ける数が全部1と0でできている ------------------ 12345 12345 ←1の桁だったら単にずらしただけになっている! 00000 ←0だったら0 12345 ------------------前にコンピューターは2進法しか分からないと書きました。2進法にははもちろん1と0しかありません!というわけで数字をずらすという命令があればかけ算がとっても楽になるのです! 論理演算命令偽機械語にもあった論理演算命令です
ところで偽機械語では1と0のことしか書いてませんでしたが、レジスタは最低でも8ビットあるので他の数も書くことができます。 それでは二つのレジスタに1,0以外の値が入っていたら一体どうなるのでしょう? 下にいくつか例を挙げましょう。 100 AND 200 =64 170 AND 85 =0 255 AND 100 =100なんだか謎めいていますが、種明かしは簡単です。機械語の論理演算命令は、2進法で表した数の対応する各桁ごとに論理演算(ANDやORなど)するのです。最初の例の説明をすると、 100=01100100 200=11001000 ↓ 64=01000000というように各桁ごとにANDを行っており、二つの数で同じ桁に1があるところ(太字)だけ1になって、それ以外の桁は0になってしまうので、こんな答えが返ってきたのでした。 OR命令はANDの代わりに各ビットごとのORをとります。 CPL命令は各ビットのNOT、すなわち反転をします。 * XOR命令ところでXORというの聞いたことがありますか?これは各ビットごとに以下のような演算をします。0 XOR 0 → 0 1 XOR 0 → 1 0 XOR 1 → 1 1 XOR 1 → 0 ←ここだけがORと違うつまり二つの項が等しければ0、違っていれば1と考えればいいでしょう。それだけならなんてことはありませんが、この命令には以下のような非常に便利な特徴があるのです。 A XOR B = C になるとすると C XOR B = A になるつまりAとBのXOR演算をした結果に対して、もう一度BでXOR演算をすると元と同じAになるのです。例を挙げると 123(01111011)XOR 58(00111010)= 65(01000001) 65(01000001)XOR 58(00111010)=123(01111011) だからどうしたって? オトナならこの例で分かってもらえるはずです・・・ ビット演算命令この命令はレジスタ内部の数の各ビット単位でいろいろな処理をしたいときに使います。
特に昔はメモリーが高価だったので、1ビットで済むような情報(例えばBGMのON/OFFとか)を保存しておくの1バイトも使うのは悪徳とされていました。2進法の1桁をこういう情報の保管に使えれば、1バイトに8つの情報を詰め込むことができるわけです。 ジャンプ命令偽機械語と同様にプログラムの実行順序を変える命令です。
ジャンプ命令には以下のように条件を付けることもできます
長くなったので続きは次のページです! |