さて読者諸君,PCは使っているだろうか.あるいはスマホでも良い.まさかガラケーから私のブログを読んでいる人間が...いたりするかもしれないが
それでも構わない.
それら機械には必ず(多分)CPUが搭載されている.現代人なら多分CPUという言葉くらいは聞いたことがあるだろう.
CPUとはCentral Processing Unitの略で,日本語に訳せば中央演算処理装置だ.
では具体的には一体何をしているの?と思われる方が大半だろう.自分はパソコンに詳しいから知ってるぞ,と思っている人間もこれが強ければつよつよPCだといううっすらとした知識しか知らないことがほとんどだろう(1年前の私がそうだった)(ただし情報科学を専門にしていてガチガチの本職の人間やらは除く).
答えよう.CPUがやっているのはコンピュータを動作させるためのプログラムを実行するための処理の大半である.
「???」と頭に浮かんだ人がいるだろうか.プログラミングもろくにやったことがないのにこんな記事を読む人間がいるのか?と思わなくもないがなにしろ素人のためを謳った記事なので何もかもを説明しよう.
まずコンピュータというのはソフトウェアがなければただの高価で重くて邪魔な箱である.いうなれば命が吹き込まれていない死体のようなものだ.肉体はそれを動かそうとする意思によって動かされている.
つまりこうだ.
これこれこうしたいという意思 ← ソフトウェア
それを実現するために体に指令を送る脳 ← CPU
実際に動く肉体 ← その他ハードウェア
我ながら実にわかりやすい表現ではなかろうか.
そしてここで結論を述べてしまうと,CPUを設計するということがどういうことかを理解するためにはソフトウェアとはそもそもどんなものであるかを理解しなければいけない.
ソフトウェアとはすなわちプログラムである.そしてプログラムとはコンピュータのための手順書である。
多くの人が使用するWordやExcel,(ジャストシステム信者に忖度するなら一太郎も)などは皆「文章を書く」だとか「表計算をする」だとかを行うために作られている.
これら目的を達成するための手順を,誰が読んでもわかるように記述するための言語がいわゆるプログラミング言語だ.電卓ソフトなら,入力された数字と+-×÷などから数値を計算して画面に表示する,などという手順がプログラミング言語で書かれている.(また,それぞれの手順の一つ一つを命令と呼ぶので覚えてほしい.)
しかしここで重要なのは,プログラミング言語とはあくまで「人間にとって」読みやすいものだ.実は(割と多くの人が知っていそうだが)コンピュータは0と1しか認識できない.この0と1というのも数字で認識しているわけではない.ただ電気が流れているか流れていないかというだけだ.
よって,機械が理解できる言語は1と0だけで表されている必要がある.それを機械語と呼ぶ.
つまり,実行できるソフトウェアを作るということは,
- 人間が理解できるプログラミング言語で手順書を書く
- その手順書を機械が理解できる機械語に変換する
という手順を踏むことである.
しかし実際のところ,プログラミング言語から直に機械語に変換するわけではない.
というのも機械語に用意された命令というのはとてもシンプルなものしかないからだ.
例えば,プログラミング言語で10の階乗を行うという手続きを書いたとする.
しかし機械語では足し算しか出来ない(としよう)ので,すべての掛け算を足し算で行うような記述にしなければならない.
人間の体の例で言うならば、プログラミング言語では「左手でものを掴む」と指示をかけるところを、機械語では「左手の薬指の第二関節を20度曲げる」くらい細かい命令しかできない。プログラミング言語でできる命令を機械語に書き下す作業はかなり複雑であることがわかるだろう。
そのような複雑な変換作業を1と0だけで行うのは非効率的であることは想像に難くないだろう.
よって,その間を埋める言語というものが存在する.その名もアセンブリ言語だ.
アセンブリ言語の命令と機械語の命令はほぼ1:1の関係をしており,機械語の直訳がアセンブリ言語だと考えてもらって構わない(実はこの2つは微妙にややこしい関係をしているのだが,それは後述).
身体の例で言うならば,アセンブリ言語は「左手の薬指の第二関節を20度曲げる」と言葉で記述できる.
それに対して機械語では身体のそれぞれの部品に番号を割り当てて(たとえば右手を1番,左手を2番,親指から小指に向かって1,2,...5番,第~関節を~度のように),「2 4, 2, 20」のように数字でのみ記述することが出来る.そしてコンピュータは0と1しか認識できないので,実際にはこれらの数字は2進数で表す.つまり「10 100 10 10100」のようになる.
(ちなみにいわゆるコンパイルという作業はこの「プログラミング言語→アセンブリ言語」の変換作業のことをいう.が,多分多くの人はプログラミング言語から機械語までの変換作業すべてをコンパイルと行っているので,どちらでとっても構わない.)
ということでここまでの話をまとめると、ソフトウェアを作るというのは、
- プログラミング言語で目的を達成するための手順書を書く
- アセンブリ言語でより細かい手順に書き下す
- アセンブリ言語で書かれた手順書を機械語に変換して0と1だけの文章にする
というわけで,ソフトウェアの作り方まではわかっていただけたのではないだろうか.
そしていよいよCPUの話になる.
今までにプログラミング言語,アセンブリ言語,機械語と3つの言語が登場したが,ゼロからコンピュータを作ろうと思ったとき,一番最初につくるのはアセンブリ言語なのである.
実はアセンブリ言語で(つまり機械語で)使用できる命令とは,CPUが実行できる命令そのものである.
例えば,2つの値同士を足し算したり,数値を保存したりするような単純な命令は,実はCPUが実行できる命令の最小単位なのである.
それらの命令を集めたものを,命令セットと呼ぶ.
これを身体で例えるならば,「右膝関節を~度曲げる」や,「首の関節を上方向に~度曲げる」などのすべての命令を網羅したものが命令セットである.
いや正確には,「何を出来るCPUを作るか」という目標を命令セットという形で決め,その仕様通りに実行できる回路を作る,というのがCPUを設計する手順なのだ.
PCでソフトをインストールするとき,x86やx64などの文字列を見たことがないだろうか.あるいは,最近では情報系のニュースでArmという単語を聞いたりすることがあるかもしれない.
それらはCPUが実行できる命令を集めたセット,つまり命令セット(≒アセンブリ言語)の種類なのである.
多くのPCで使用されているintelのCPUは,たいていx64という命令セットを実行できるように設計されている.そのため,プログラミング言語で書かれたプログラムはx64の命令に変換され,x64に対応したCPUで実行可能になるのだ.
様々な種類のCPUがあれど,ほとんどのPCで共通のソフトウェアが動作するのは命令セットが共通だからなのである.
というわけで,まとめに入る.
結局のところCPUを作るというのはどういうことかというと,
- 命令セットをつくる
- その命令セットを実行できる回路を設計する
という2つのステップを達成することなのである.
以上,CPU設計のイントロダクションでした.
次回以降は論理回路の基礎について書いていこうと思います.