プログラミングのための生の計算機イメージ

プログラミングについて根本的なところから学ぼうとする場合、(最低限の) 生の計算機のイメージがないとピンとこないんじゃないかと思っています。そ こで、この資料で出来るだけ直感的に(?)理解できるように説明を試みます。 (成功するかは謎ですが)

目次

そもそも、プログラムって何?

すでにプログラミングを学んでいる人の復習もかねて、最初に「プログラム」と は何かを再確認しておきます。

計算機は、よく言われるように、ソフトウェア(プログラム(と、関連デー タ))をインストールして実行しなければ何もできません。逆に考えると、プ ログラムとは、計算機が何か役に立つような仕事をするための手順(段取り) を計算機にわかるように記述されたもの、というとらえかたもできます。

では、プログラミングって何?ということになるわけですが、これは計算機にな んらかの仕事をさせるための手順を 計算機がわかるように書いてあげる、と言う ことができるでしょう。この『計算機がわかるように』 というのがミソです。つまり、計算機は人間の言葉 (自然言語とい うことがあります) が理解できませんし、仕事の仕方も(手足や口もな く)限られてますから、計算機がわかるような言葉、すなわち プログラミ ング言語 計算機が実行できる 形で書いてあげる、というこ とになるわけです。

この『 実行できる形で 』というのもミソで、C言語のようなものは、 実は計算機では『直接は』実行が出来なくって、実行できる形に 変 換 するか、 そのプログラミング言語を実行できるプログラムを介して実行 しないといけないわけです。

前者については後に述べるように、最終的には 機械語=ビットの並 び になっています。これをつくる方法としては、プログラム言語を 「 コンパイル(+リンク) 」して実行イメージを作る方法がありま す。後者の実行方法としては、プログラム言語を1ステップ(行)ずつ読みだ しては解釈して実行することのできるプログラム (インタープリタ) を介して実行するやりかた等があります。

厳密にいうと、組み込み等を除くと、今日の計算機環境では生の機械語で直接 処理する(させる)というのは、(ライブラリ、ミドルウェアを含んだ広い意 味での)OS (Operation System, MS 的に言うと「基本ソフト」) 自体を除いてほぼありません。OSのサポートなしでは動けないほどソ フトウェアの規模は大きくなっています。とはいえ、OS自体は機械語レベル で動いている、というのもまたまぎれもない真実です。

小まとめ

まとめると、プログラミングとは(デバッグ工程とかを除くと);
  1. まずどんなプログラムが必要かを考え[設計]
  2. 編集用プログラム(エディタ)でプログラムを書き[コーディング]
  3. 実行できる形に変換し[コンパイル…インタープリタ言語の場合は不用]
  4. メモリにロードして実行する。
という手順をふみます。詳細は述べませんが、この編集用プログラムやコンパ イラ、インタープリタ、あるいはメモリにロードして実行させるもの自体もそ れぞれが (事前に書かれた)プログラム であることに注意しておい てください。

じゃ、計算機って何物?

繰り返しになりますが、要するに、何か入力して、何かその入力に対 して処理をして、何かその結果を出力するもの、です。こ の「何か」がいろんな場合があるわけですが、基本は同じです。例えば入力が マウスのイベント(クリックした、等)で、処理が「アプリケーションの終了」 で、出力がウィンドウを閉じる、ということだったりします。

構成は?

良く言われる説明ではありますが、(von Neumann タイプの)計算機の場合、 構成要素は3つ、メモリ演算部 (CPU) 入出力 (Input/Output)です。で、メモリはプログラム(処理手順自体)とデータ (処理対象)をおいておくところです。メモリには番地がふってあっ て、0、1、2…と順に並んでいます。この番地のことをアドレスと いいます。最近はほとんど8ビット(=1バイト)単位ですが、ここで例とし て利用する GMC-4 では4ビット単位でアドレスをふっています(後述)。 また、CPUには(処理の際の手もとのメモ書き用として)レジスタと いうメモリを(すこしだけ?)持っているものが多いです。

CPU は、所詮は状態機械です。状態機械というのは聞きなれない かもしれませんが、要するに状態(データ)を内部に持っていて、その状態に 応じて挙動(動作、データ入出力も挙動のうち)が変わるような機械 (メカとは限らない)です。CPUの構成は、組み合わせ回路順 序回路(=論理回路+メモリ)です。例えば、1ビットの足し算(!?) は、以下のように、AND (論理積)、OR (論理和)、NOT (論理否定)を組み 合わせた回路(半加算器, Half Adder (HA))になっています。
Half ADDER  
 
 
 
 
 
 
 
 
 
A B S(elect) C(arry) 2進数
000000
101001
011001
110110

さらに、これを組み合わせて、繰り上がりに対応したものが全加算器 (Full Adder, FA) と呼ばれています。3ビットを足した結果を 出力します。
Full ADDER
A B X S C
00000
10010
01010
11001
00110
10101
01101
11111
そして、半加算器1つと、全加算器 n-1 個を組み合わせると、n ビットの加算 器が出来あがります。例として4ビットの加算器を示します。
Four ADDER

以下の演習で、ちょっと馴染んでください。

論理演算の演習
2進数演算の演習

さらに、上の論理回路がどう組み合わされば CPU になるかを真剣に知りたい人 には 「CPUの創りかた」 がお勧めです。

ちなみに以下が、その回路図の抜粋(単純なゲートだけじゃなくロジックIC まるごとも使われている)です。

CPU内のレジスタを含め、メモリ=(補助記憶を含む)記憶装置に計算の処 理手順(プログラム)処理対象(データ)がどちらも置かれ る (von Neumann type) というのが、今日のコンピュータの基本です。別の言 い方をすると、所詮はビット列なので、全く同じビット列をデータとして読む か命令(プログラムの一部)として読むかは状況次第、というわけです。

メモリにプログラムとデータがおいてるって、どーゆーこと?

*これを理解できているかどうかがこれから先の分かれ目ですんで、よくみて おいてください。
要するに、(最近のほとんどの)計算機の動作原理は
  1. まずメモリからデータを取り込み (fetch)
  2. それを機械語として解釈し (decode)
  3. 解釈したように実行する (execute)
の連続です。そのデータは最初にどないしてメモリにおくんや[モニタ、OS、 等と呼ばれるプログラムの担当]とか、割り込みはどうなるんや、とかは別の 機会とします。

例でみてみましょう。ここで は 学研の「大人の科学」 No.24 ふろく4ビットマイコン (命令だけなら このペー ジ が見やすいかも)の動きにしたがうとします。

たとえ話も参照してください。
この仮想計算機は4bitが1ワードです。機械語命令(オペコード)は1ワード で、オペランド(引数)は命令に応じて0〜2ワードをとります。レジスタは A,B,X,Y (と、その補助となる A', B', X', Y') を持っています。またフラグ が1つだけあります。(下図参照)
ADDER
メモリに16進表現で

00:8
01:1
02:9
03:2
04:1
05:F
06:0
07:5

と並んでいたとします。

  1. 演算部はまず最初の 8 (4bit) を読み込みます。こ の4ビットが動作の指示(この場合は即値の設定)となります。次の4ビット が対象となる数(1)です。ということで、この場合はつまり「Aレジスタに 1を格納する」という意味です。
    と言われてもぴんとこないかもしれませんが、CPUの内部で、このような動 作をするように、論理回路(と、順序回路・メモリ)が組みあわさっている、 ということなのです。

    また、ここで注意してもらいたいことは、このように原始的な部分では 計算機への命令とデータに本質的な差はなく、どちらも所詮はメモリ上の1と 0の並びであり、それをどう解釈するかはその時点での計算機の状態次第であ る、ということです。

  2. 次に、演算部は2番地の 9 を読み込みます。上と同 様に解釈して、次の4ビットが対象となる数(2)で、それを今のAレジスタ の値と加えて、その結果を新たにAレジスタの値とする、ということになりま す。上でAは1になっているので、Aレジスタの値は 1+2=3 になるわけです。

  3. さらに次に、演算部は4番地の 1 を読み込みます。 1 を読み込みます。 これは、「Aレジスタの値を数字 LED に表示する」ということですので、ここ では加算された結果の3を表示します。
    この命令はかならず実行フラグを1にするのですが、ここでは説明は略します。 さらに、つぎに演算部は5番地の F を読み込みます。 これは、「続く2ワード(8bit) の値(この場合は 05)をアドレスとして、実行 フラグが1の場合、指定されたアドレスに制御を移す」ということで、前の命 令で実行フラグは1になったのでこの命令を実行する、ということは、自分自 身を再度実行せよ、ということになります。つまりここで無限ループに入るこ とになります。この計算機は終了することを知らないので、終わりたいときは 無限ループにする、ということなのですが、ここではそういうものだ、くらい に考えていてください。
    つまり、上の 4bit の 8 つの並びで、「1+2を計算し、その結果を表示しろ」 というプログラムだった、というわけです。

で、アセンブリ言語

講義用スタイル
印刷用スタイル