序論的なこと

この授業では機械語(とその相棒であるアセンブリ言語)について学ぶ。 「機械語」という名前はすでに知っているはずだ。 例えばC言語でプログラムを作ったとき,実行するためにはコンパイルという作業が必要だった。コンパイルとは,ソースコードを翻訳し,機械語プログラムを生成することだ。

なぜこの手順が必要なのか?(これもすでに知っているはず。)「我々のコンピュータは機械語プログラムしか実行できない」からだ。

簡単な答としてはそれでいい。 でも,情報学群ですでに1年半学んだ諸君にはもう少し先まで考えてもらいたい。 なぜ「我々のコンピュータは機械語プログラムしか実行できない」のだろうか?


……それは,「『機械語』しか実行できない機械」の方が作るのが容易だから。と言うより,そうでない機械を作るのは困難すぎて非現実的だからだ。

2年次前期に「論理回路」について学んだと思う。AND・OR・NOT回路と,それらを組み合わせて作る加算回路やフリップフロップなどについて学んだはずだ。 我々のコンピュータ,つまり「電気で動くプログラム自動実行機械」を作るために使える材料は,基本的にこれらの論理回路だけだ。演算回路や順序回路を膨大な数組み合わせ,プログラムされた事柄を順に自動的に実行するよう作られた機械,それが「コンピュータ」だ。 「論理回路」で学んだ各回路の機能の単純さを考えれば,「プログラム自動実行機械」を作るのがどれだけ複雑で困難なことかわかると思う。 「実行すべき命令」を,非常に単純かつ機械の都合に合わせたものにしなければ,現実に動く機械は実現できないというわけだ。

プログラム実行機械の構造

コンピュータは最低限,プログラムやデータを格納する主記憶装置と,プログラムを実行する中央処理装置 (CPU) からなる(下図)。 CPUが主記憶装置から1命令ずつ読み出し(フェッチ)して実行することで,プログラムが実行される。

機械語命令は8〜32ビット程度のビット列であり,それを順に並べたものが機械語プログラムだ(命令とその引数がすべて番号で表されている,と考えればよい)。 CPUごとに,実行できる命令の集合(命令セット)と各命令を表すビット列が決まっている。

ビット列である命令の読み出し → 実行 → 読み出し → 実行 → … という処理が繰り返されるところは,オルゴールの仕組みに似ている。 穴の有無つまり0と1の情報の並びが,何をどういう順番に実行するか(オルゴールの場合はどの音をどういうタイミングで鳴らすか)を表した「プログラム」に当たる。 それらが時間につれて順に「実行装置」(オルゴールの場合は櫛歯)に送られ,「実行」される。

CPUの内部には,加減算等の演算を行う演算装置 (ALU) や,被演算数や演算結果を一時保管するためのレジスタが組み込まれている。 1命令でできることは基本的には以下のようなものだ。

  • 主記憶装置からレジスタへ,またはレジスタから主記憶装置へ,ビット列をコピーする。(転送
  • レジスタ中の2進数を演算装置に入力し,結果をレジスタに書き戻す。(演算
  • 命令読み出し位置を手前に戻す。(ループ
  • 減算結果が0のとき(つまり2数が等しいとき)に命令読み出し位置を変更する。(条件分岐

このような単純な命令であれば論理回路の組み合わせで実現でき,かつ,この4種類(転送・演算・ループ・条件分岐)の命令があればどんなアルゴリズムでも実現できる(専門用語で「Turing完全」と言う)。

この授業で機械語命令を使って実際にプログラムを作成することで,具体的にどんな命令があるか,どう組み合わせたら高級言語プログラムと同じことができるか,理解できるようになるだろう。

機械語を学ぶ意義

この授業の目的は主に,「計算機械の仕組み」を学ぶことだ。その方法として一番直接的と思われるのは,実際に電子回路の素子を組み合わせて簡単なコンピュータを作ってみることだ(これはとても勉強になるので興味があればぜひやってみるとよい。ただし,レジスタが1〜2個,演算が「1増やす」「1減らす」しかない単純なコンピュータでも,作り上げるのは相当手間が掛かる。参考: CPUの創りかた)。

しかし,実際にコンピュータを作ってみるにしても,その前に,まず機械語について学習しなければならない。なぜなら,「どのような機械語命令を受け付けるか(= 機械語命令セット)」がそのコンピュータの「仕様」(= どういう操作が可能か,その操作をするとどう振る舞うか)だからだ。何を作るのか決めずに物を作ることはできない。 論理回路の組み合わせで実現できるくらい単純で,かつ,どんなプログラムもそれに翻訳できるくらい万能の機械語命令セットをまず決め,それを実現するような電子回路を設計していく,という順序でコンピュータは作られる。 世界最初のコンピュータが作られたときには様々な試行錯誤があったと思うが,僕たちの周りにはすでにコンピュータがあるので,一から考えなくても既存のコンピュータの機械語を手本として学ぶことができる。 この授業は,「論理回路」「計算機アーキテクチャ」などの「計算機械の仕組み」を学ぶ課程の途中の1ステップであり,「計算機械はどのような機能(= 機械語命令)を利用者に提供しているか/しなければならないか」を学習する授業,ということになる。

また,機械語の知識は,計算機械(= ハードウェア)の仕組みを理解するためだけでなく,その上に構築されている「ソフトウェアの世界」を理解するためにも重要だ。 ソフトウェアが形作る「仮想の世界」「情報の世界」は,機械語という「現実世界との接点」にまで分解し翻訳しなければ現実のものにならない(絵に描いた餅でしかない)。 ソフトウェアの世界を支える土台である機械語について知ることは,ソフトウェアの世界をより深く理解することに繋がる。例えば,コンパイラなどの言語処理系が具体的に何をやっているかは,翻訳先の言語である機械語のことがわからなければ理解が難しい。Linuxなどのオペレーティングシステムがやっている仕事や,「ソフトウェアで実装した計算機械」である仮想機械 (virtual machine) の仕組みを理解するのにも,機械語の知識は不可欠だ。

まとめると以下のようになる。

  • コンピュータとは具体的にはどのような機能を提供している機械なのか知るために,機械語を学ぶ必要がある。
  • ソフトウェアが現実にはどのような形に分解されて実行されているのか知るために,機械語を学ぶ必要がある。

さて,機械語について学ぶことは重要だが,この授業では「流暢に機械語プログラムを作成する」ことは目指していない。「どのような命令があるか」「それだけあれば本当にどんなプログラムでも翻訳できるか」といった知識の方が大事だ。 ただ,機械語もC言語やJavaと同じ「プログラム記述手段」であるし,それを学習する手っ取り早い方法は「実際に使ってみる」(= プログラムを作ってみる)ことだと思われる。 そこでこの授業でもプログラムを作成する演習を多く行うが,目的は機械語というものを理解することであって,「機械語によるプログラム開発の練習」が目的ではないことに注意してほしい。 頭を働かさずに手だけ動かしても得るものは無い,ということでもある。

results matching ""

    No results matching ""