標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第65回]

●LXI命令

今回はLXI命令について説明します。
LXI命令は16ビットレジスタ、BC、DE、HL、SP(スタックポインタ)に、命令コードに続く2バイト(16ビット)の値を書き込む命令です。
MVI命令は、8ビットのレジスタに、命令コードに続く1バイト(8ビツト)の値を書き込む命令でしたが、それの16ビット版です。

命令コードは次の通りです。

命令コード(2進数)   命令コード(16進数)  ニーモニック    
00000001           01          LXI B,data16
00010001           11          LXI D,data16
00100001           21          LXI H,data16
00110001           31          LXI SP,data16

data16は2バイト(16ビット)の値です。
命令コードの次のメモリアドレスに、データの下位バイトを置き、さらにその次のメモリアドレスに、データの上位バイトを置きます。

たとえば、アセンブラニーモニックで、

LXI B,1234

と書くと、この命令は、16進数のデータ1234をBCレジスタに書き込め、という命令になります(Bレジスタに12を、Cレジスタに34を書き込みます)。
マシン語コードは、データを含めると3バイトになります。
上記のLXI B,1234 が、メモリの0100番地から書かれている例を下に示します。

アドレス  2進数      16進数  ニーモニック
0100   00000001   01       LXI B
0101   00110100   34      (下位データ)
0102   00010010   12      (上位データ)

この命令はMVI命令を使って
MVI B,12
MVI C,34
と書いたのと全く同じ結果になります。
それならわざわざLXI命令など作らなくてもよさそうなものですが、MVI命令を使うと、4バイトになります。LXI命令なら3バイトで済みますから1バイトメモリが節約できます。
昔、8080が出来た当時はメモリがとても高価だったので、1バイトでも節約できる命令は存在意義があったのかもしれません。
なお、SP(スタックポインタ)に値を入れることはMVI命令ではできません。SPに値を入れるにはLXI命令が必要です。

●8080のニーモニックは不統一?

8080はどういう経緯で世に出てきたのか、いまひとつよくわからないのですが、なぜかつぎはぎだらけで不統一なところが目に付きます。複数の開発者の間で意見の不統一があったのかもしれません。

その顕著な例は8080のアセンブラニーモニックに見ることができます。
今回説明したLXI命令は、Load immediate register pair というところから命名されたように思えます。
8080のニーモニックでは16bitのレジスタを示すのに、Xを使います。多分expand(拡張)の意ではないかと思います。

でも8ビットの命令は、MVI(Move immediate)なのに、なぜ16ビットだとLoadになってしまうのでしょう?
対象が8ビットならMOVで16ビットならLoadにしたのか?というと、そのようにも思えますが、ではなぜ?と考えてみても、今ひとつその根拠はあいまいな気がします。

前回説明した、LDAはAレジスタが対象ですから8ビットなのですが、アドレスを指定している部分は確かに16ビットです。
しかし、なんだか、こじつけのようです。

MOVの場合は、レジスタとメモリの間でのデータ転送で、
MOV A,M と MOV M,A のように、メモリからレジスタへのデータ書き込みでも、レジスタからメモリへのデータ書き込みでも、同じMOVですから、すっきりしています。

ところが、LDAはメモリからAレジスタへのデータ書き込みで、これはLoadです。
それに対してSTAはAレジスタからメモリへの書き込みで、こちらはStoreのようです。
うーん。どっちかに統一してよ、と言いたくなります。

ちなみにこれらの命令は、Z80アセンブラではすべてLDに統一されています。
面白いことに、8080はその後16ビットCPUの8086へと発展していくわけですが、さて、このあたりの命令が8086アセンブラではどうなったかといいますと、やっぱりね、と思わず言ってしまいそうになります。
全部MOVに統一されてしまったのです。

しかし、LDではなくてMOVに統一したあたりが、なんとなくIntelのZilogに対する、意地というか面子というか、そのようなものを感じてしまいます。

●LXI命令のタイミングチャートです



これはもう、JMP命令やSTA、LDA命令のT4〜T7そのままという感じです。
JMP、STA、LDAでは、2バイトの値をメモリから読み込んで、ワークレジスタWKL、WKHに格納しましたが、LXI命令はワークレジスタの代わりに、BC、DE、HL、SPに格納します。
STA、LDAではT4〜T7のあとにまだ処理が続きましたが、LXI命令は、T4〜T7で完了してしまいます。

レジスタがBC、DE、HLのときは、命令コードのbit5、bit4をそのままd2、d1に送るだけでレジスタを指定できます。
しかしbit5=1、bit4=1はSP(スタックポインタ)を選択することになり、d3〜d1=”010”にする必要があります。
ですからd3=0、d1=0です。
d3〜d0は抵抗でプルアップされているため、何もしないときは”1”になります。ですからd2は指定する必要がありません。
d3〜d0とレジスタの関係については「レジスタコード表」([第27回])を参照してください。

●LXI命令の回路図です



実に簡単な回路です。
STA、LDAと同様に、PCtoReg16をアクティブにしています。
PCtoReg16はJMP命令の回路図([第62回])を参照してください。
op5=1、op4=1のときはd3=0、d1=0にしています。
そのほかのときは、d2=op5、d1=op4になります。
2008.9.12upload

前へ
次へ
ホームページトップへ戻る