★ OPコード秘話

 アセンブリ言語は、アセンブラによって16進数のマシン語に変換される……と、一般的には解釈されている。もちろん、16進数というのは人間向けのものであり、実際には2進数の情報となっていることは周知の事実であろう。
 アセンブラを使いこなしてゆくと、次第にニーモニックと16進数の関係が読めてくるようになる。中には、ニーモニックからアセンブラを介さずに16進数への変換ができるまでに熟練(?)し、自らを「人間アセンブラ」と称する者も過去には少なからず存在した。
 しかし、そこで「マシン語は2進数である」という意識がないところが、悲しいかな人間アセンブラの人間たる所以なのである。
 確かに、ニーモニックから16進数へは直結したかもしれないが、16進数はあくまでも人間向けの表記。コンピュータ自身は、16進数などまったく眼中にないということを忘れてはならない。
 これは、単にCPUが「2進数で命令を解読している」という意味ではない。マシン語には、2進数ならではの英知の結晶が隠されているのである。
 いわゆる「Z80ニーモニック表」には、ニーモニックに対する2進数がOPコード(オペレーション・コード)として掲載されている。
 おそらく、かなりアセンブリ言語でプログラミングをした経験のある方でも、OPコードまで真剣に見つめたことはないだろう。これは、アセンブラを自作する段階になって、ようやく必要性を感じるものである。
 しかし、このOPコードこそが2進数ベースで見たマシン語の正体。ニーモニックとマシン語(16進数)の対照表を見ると、各命令を体系的に順番に並べてあるように見えるが、そこには「そうでなければならない根拠」が存在しているのだ。
 例えば、8ビットレジスタ間でのロード命令(LD r,r')に着目してみよう。この命令におけるOPコードは次のようになっている。

┌─── OPコード ───┐ LD r,r'   0 1 r r' b7 b6 b5 b4 b3 b2 b1 b0 ※ b5〜b3で「r」を示す。b2〜b0で「r'」を示す。 Bレジスタ=000 Cレジスタ=001 Dレジスタ=010 Eレジスタ=011 Hレジスタ=100 Lレジスタ=101 Aレジスタ=111 ※ 参照 (HL)=110

 OPコードは、正に2進数ベースで見たマシン語のことであるが、この「r」と「r'」に相当する8ビットレジスタには、きちんと3ビットの値が割り当てられているのだ。
 16進数となったマシン語で見てしまうと、8ビットレジスタ間の移動は40H〜7FHということしかわからない。しかし、そこには「命令が並ぶ順番の確固たる根拠」が存在していたわけである。
 無意味とも思える同レジスタ間の移動命令(LD B,B ……など)も、2進数ベースで見ることによって存在理由が判明する。つまり、必要があっての命令ではなく、設計上の都合ということが伺えるのだ。
 ちなみに、HLレジスタが指し示す中身という意味の(HL)は、8ビットレジスタと似たような命令が用意されているにもかかわらず、ニーモニック表からしてまったく別格の扱われ方をしている。
 だから、ここでも「LD (HL),(HL)」という命令はなく、01110110=76H の値に対しては無関係のHALT命令が当てはめられているのだ。
 このように、マシン語をOPコードの観点から見てゆくと、当時の設計者の苦労や、命令が存在する必然性などが微妙に浮かび上がってきて、思わず時空を超えて会話をしているような気分になる。数語というと、いかにも無機質的な雰囲気が漂うが、こんなところに言語としてのコミュニケーションがあるのかもしれない。