最近、FPGAなどを使ってCPUを自作する記事を目にするようになりました。CPUの命令コードは数字ですから、アセンブラソースを1行1行手で命令コードに変換していく(ハンドアセンブルする)ことになります。昔は、このためにコーディング用紙というものが売っていました。
最近のPICなどのマイコンには開発環境が用意されており、アセンブラなど必要な道具はすべて入っています。ですから、用意されているアセンブラを使うことがあっても、アセンブラを自分で作るという機会はなかなかないと思います。ここでは、アセンブラを作ってみることにしましょう。
PHPでアセンブラを作る
アセンブラをどの言語で作るかですが、今回もPHPを使ってみました。フォーム上にソースを入力すると、バイナリが出力されます。対応しているのはPIC16Fの命令セットで、今回のアセンブラプログラムを使って開発環境で作ったものとまったく同じバイナリが得られました。
このアセンブラプログラムのPHPのソースはリスト1のようになります。
今回は、ソースと同じ場所にincludeというディレクトリを用意する必要かあります。
まず、標準の開発環境であるMPLABをMicrochip Technorogyのページからダウンロード、インストールします。インストール後にできたMPASM suiteの下にある*.incを、includeの中にコピーしてください。アセンブラソース中でincludeを使うと、ここから読み込まれます。
アセンブラの擬似命令ですが、すべてをサポートしているわけではありません。ただし、アセンブラそのものを自作するわけですので、必要な擬似命令は自分で追加することができます。
また、ソースの中に書ける式も、加減と、ビットの論理積・論理和だけです。これも、必要に応じて自分で追加しましょう。
アセンブラ作りの第一歩
さて、アセンブラなんて100年ぶり、という方もいらっしゃるでしょうから、ちょっと復習です。
アセンブラの最大の特徴は、原則としてソースの1行がCPUの1命令に対応する、ということです。CPUの命令は、すべて番号で表わされます。1番がif、2番がgotoといった具合です。さすがにこれでは、読むのも書くのも大変です。そこで、命令の番号を文字にしたものがアセンブリ言語です。CPUが違えば、アセンブリ言語も違ったものになります。
命令に与えるパラメータも、その命令で扱えるものに限られます。C言語では*(q++)=*(p++);
と書けますが、アセンブラでは1ステップずつに分解しないといけません。Z80にはLDIという命令があり、DEレジスタとHLレジスタに限ってこのような処理が可能でしたが、多くのCPUでは複数の命令が必要です。
こうして見ると、アセンブラは融通の利かない時代遅れの言語に見えるかも知れません。しかし、CPUの全ての機能を100%引き出すことができるのは、アセンブラだけです。たとえば、C言語のプログラムが起動するときは、スタックやデータのためにメモリを初期化する必要があります。アセンブリ言語ではメモリを使わないでプログラムを動かすことができるのですが、C言語ではこういうことはできませんから、起動時の処理をC言語で書くことはできないわけです。同じ理由で、割り込み処理やOSなどを書く際も、アセンブラは避けて通ることができません。
そんなわけで、この機会にアセンブラに少しでも興味を持っていただければと思います。次回はアセンブラの内部がどうなっているのかを解説していきます。