CPUよもやま話(機械語の正体)
前回は、マルチプレクサに繋がる7つの配線を、4ビットのオペコードとフラグでどうやって操るの?ってところで終わりました。
この?の部分には、任意のオペコードとフラグが入力されれば、それを解読して必要な信号を出力する装置を入れる必要があります。例えば0001が入力されれば0111001が出力される、といったように。
このように圧縮・暗号化された符号を解読するための装置をデコーダといいます。特にこの場合は、圧縮された命令を解読するためのものなので命令デコーダといいます。
反対に、実際の信号をある規則に従って圧縮・暗号化することをエンコードといいます。多くの配線への信号を、より少ないビットの組み合わせに圧縮したもの。これが、機械語です。
機械語は回路設計者が決定します。とりあえず、LTD4では下のようにしてみました。(アセンブリは動作をイメージしやすくするための参考記載です)
さて、この一覧表どおりに出力される命令デコーダを作る必要があります。
Logisimで命令デコーダを自動生成してみる
Logisimには真理値表から論理回路を自動生成する便利な機能があります。せっかくなのでこれを使ってみたいと思います。
まず、ProjectからAnalyze Circuitを選択します。
次に、Inputsダブで入力ピンの名前を入力し、一覧に追加します。
同様に、Outputsタブで出力ピンの名前を入力し、一覧に追加します。
Tableタブで真理値表を作成します。入力側の組み合わせに応じて、出力側を1、0、X(どちらでもよい)のいずれかに設定します。
なお、入力側は変更できません。X(どちらでもよい)といった指定もできないので、Xの場合は0と1のどちらでも結果が同じになるように真理値表を作成する必要があります。
真理値表を埋めたら、Build Circuitを押します。その後、表示されるダイアログボックスで回路名を入力して了解を押すと、回路が自動生成されます。
で、出来上がった回路がこちら
やけに、縦長じゃないか?( ̄q ̄;)
とりあえずこれが最後のピースなので、?の部分に当てはめます。(入力と出力の向きが逆なので180度回転させます)
これで完成!
とりあえず動かしてみる
特に面白いプログラムを思いつかなかったので(←ぇ)、無意味にループさせて10回目でループを抜けるというのをやってみます。
高水準言語的に書くと
- For i = 1 To 10
- Next
アセンブリ言語で書くと
- MOV B,6 '比較用の6をレジスタBに転送
- ADD A,1 'レジスタAに1を加算した結果をレジスタAに転送
- ADD B,A 'レジスタAとレジスタBを加算
- JNC 0 '直前の加算結果が15以下なら0番地にジャンプ
- JMP 4 '4番地に無条件ジャンプ(つまりこの行で永久ループ)
機械語で書くと
- 0100 0110 [46]
- 0111 0001 [71]
- 0110 0000 [60]
- 1011 0000 [B0]
- 1001 0100 [94]
- ※カッコ内は16進数
です。
これをメモリに0番地から順番に記憶させておいて、0番地から実行させてみたいと思います。(クロックは4Hz)
すごく地味!
まとめ
普段使っているPCも、ビット数・レジスタ数などが違うだけで根本的には内部でこんなことをやっています(1秒間に数十億回という速さですが)。
果てしなく続くオープンワールドのゲームでも、Excelでも、YouTubeの再生でも、人工知能でも、ビット単位で見ればこんなもんです。これらはすべて、根本的な部分は変わらず、ハードウェアの高性能化とソフトウェアの工夫で実現されています。
・・・・・・っていう、どの立場から語っているんだよ!的な、よもやま話でした。