Index

CPU とメインメモリ

初版: 2005-05-22

CPU の役割

パソコンに代表されるコンピュータは表計算、ワープロ、インターネット接続やビデオ編集まで幅広くの用途で使われ、ビジネスから家庭まで至るところで活躍しています。これらコンピュータは多くの部品から構成されていますが、その中でも頭脳にあたる最も中心に位置し、各部品とデータをやりとりして、全体を制御する役割を持つのが CPU (Central Processiong Unit) です。何でもできるコンピュータの頭脳である CPU というと、たくさんの機能を持ち多くのことができそうですが、実はそうではありません。基本的に CPU ができることは各部品とのデータの入出力とそのデータに対する演算だけしかありません。他の構成部品とデータをやりとりしながら、コンピュータ全体として初めて何かの機能を提供できるのです。例えば、単純な電卓機能でも CPU だけでは提供できません。まず計算したい数値を人間がキーボードに打ち込みます。CPU はキーボードからデータを受け取り、その計算を実行します。そして計算結果となるデータはディスプレイに送られ、ディスプレイはそれを表示します。これを見て人間は計算結果を知ることができます。

CPU が扱うデータ

電卓機能で CPU が扱ったデータには何があるでしょうか。まずキーボードから入力された数値のデータが扱われました。実はこの他に電卓機能を実現するための手順を表したデータが扱われています。これは CPU への命令を順番に並べたもので、一般にこれをプログラムと呼びます。コンピュータに電源を入れた直後、最初は CPU は何も知りませんから、電卓機能の手順というデータを与える必要があります。CPU はその手順に従い、キーボードから数値のデータを入力し、その計算結果をディスプレイに出力します。以上のことから CPU が扱うデータには 2 つの種類があることがわかります。CPU への命令 (Instruction)と、キーボードから入力された数値のような単なるデータ (Data)です。

データを格納するメインメモリ

ここまでで CPU は 2 種類のデータを扱うことがわかりましたが、1 つ疑問が起こります。CPU が扱うこれらのデータは一体どこに格納されているのでしょうか。CPU はデータの入出力とそれを演算する機能だけを持つ装置であり、データを格納するための機能を持っていません (*1)。そこで CPU が扱うデータを格納するための装置が必要になります。これをメインメモリ (Main memory) と呼びます。ここでデータを格納するための装置にはハードディスクもあるではないか、と思われた方がいるかもしれません。確かにメインメモリもハードディスクも共に記憶装置 (Storage) ですが、メインメモリは主記憶装置 (Primary storage) と呼ばれるのに対し、ハードディスクやフロッピーディスクなどは補助記憶装置 (Secondary storage) と呼ばれます。これらの決定的な違いは主記憶装置がなければコンピュータは動作しませんが、補助記憶装置がなくても動作できることです (不便かもしれませんが)。これは CPU は主記憶装置に格納された命令のみを実行できるように設計されており、補助記憶装置上の命令を直接実行することはできないからです。主記憶装置であるメインメモリはコンピュータにとって最も重要な記憶装置ですが、電気的にデータを蓄えているためコンピュータの電源を切るとデータは全て失われます。これを補う目的で、つまり電源を切ってもデータを失わない記憶装置として、補助記憶装置であるハードディスクやフロッピーディスクは存在します。

CPU 内部のレジスタ

CPU が扱うデータはメインメモリに格納されていることがわかりました。では CPU はメインメモリ上のデータを全て、直接読み込んだり書き込んだりするのかというとそうではありません。メインメモリは CPU にとっては外部の装置であり、データの操作を全てメインメモリに対して行うことは効率の良いことではありません。そこで CPU はその内部に数バイト程度の小さなメモリを複数持っており、メインメモリから入力したデータをそのメモリに一時的に蓄えてデータを操作します。このメモリをレジスタ (Register) と呼びます。レジスタは CPU が内部で用いるメモリであり、最も高速なメモリとなります。レジスタは決して大きな容量を持っているわけではなく、その数にも限りがありますが、一般にレジスタを効率よく使ったプログラムはそうでないものに対して、非常に高速に動作します。

メモリアドレスの指定とレジスタの指定

単純にメインメモリから CPU へデータを入力するといっても、メインメモリのどの部分のデータを入力するのか指定する必要があります。メモリはその内部でデータを 1 Byte ずつ区切って管理しており、その一つ一つに一連の番号を割り当てています。これをメモリアドレス (Memory address) といいます。CPU はメインメモリからのデータの入力の際に、メモリアドレスによりそのデータを指定します。ここでメモリアドレスは無限というわけではありません。CPU が使用できるメモリアドレスの大きさは決まっていて、それぞれの CPU によってその大きさは変わってきます。この使用できるメモリアドレスの大きさをメモリアドレス空間 (Memory address space)といいます。例えばメモリアドレス空間が 32 bit の CPU があった場合、その CPU がメモリアドレスとして扱える範囲は 2 の 32 乗であることから 0 から 4294967295 までとなり、これはつまり 4 Giga Byte までのメインメモリを扱えるということになります。メインメモリがアドレス指定によりデータの場所を指定するのに対し、レジスタの指定はより単純です。CPU には複数のレジスタが存在していますが、それぞれに名前が割り当てられており、その名前によりデータを持つレジスタを指定します (*2)

命令の実行

では実際にメインメモリに格納されたプログラムが実行される様子を見てみましょう。CPU とメインメモリのやりとりの大まかな流れがわかるように、この例の処理はメインメモリ上のデータを加算し、その結果をメインメモリに戻すという単純な処理です。

プログラム実行前
図 1: プログラム実行前

まず図 1 がプログラム実行前の CPU とメインメモリの状態です。命令とデータがメインメモリに読み込まれているのがわかります。またレジスタの中のデータは 0 で初期化されています。ここでメモリアドレスが 1 ずつ区切られていないことに疑問を感じた方がいるかもしれません。これは命令やデータは全て 1 Byte で表せるものではなく、ほとんどの場合、複数のバイトで 1 つの命令やデータを表しているため、見易さを考慮して表しています。図 1 の場合は命令、データ共に全て 4 bytes で表されていることがわかります。ここから命令を順に実行していく様子を見ていきます。

プログラム実行 1
図 2: プログラム実行 1

図 2 は CPU が 1 つ目の命令である「メモリアドレス 116 番地のデータをレジスタ r0 に入力」を実行した直後の状態を表しています。メモリアドレス 116 番地から存在するデータ「1」をレジスタ r0 に入力しています。ここで次の命令に移るわけですが特に何も指定がない場合、CPU は直前に実行した命令の次のメモリアドレスに存在する命令を順次実行していきます。

プログラム実行 2
図 3: プログラム実行 2

図 3 でも同様にメモリアドレス 120 番地から存在するデータをレジスタ r1 に入力しています。

プログラム実行 3
図 4: プログラム実行 3

図 4 ではレジスタに格納されたデータに対する演算を行っています。ここで次のように疑問に思った方がいるかもしれません。わざわざレジスタにデータを入力してからデータの演算を行わなくても、メインメモリ上のデータを直接演算すればいいのではないか。これは CPU がメインメモリ上のデータ同士を演算する機能を持っているかということに依存します。つまりそのような機能を持った CPU であれば、直接メインメモリ上のデータを演算しても構いません。しかし一般的には、メインメモリ上にあるデータは一度レジスタに入力してから演算する方が効率がよくなることが多いでしょう。メインメモリは CPU にとっては外部の装置ですから、入出力には時間がかかります。レジスタを効率よく使いまわすようにして、できるだけメインメモリに入出力する回数を減らした方が速度を上げることができます (ただし今回の例ではレジスタを使いまわしてはいません)。

プログラム実行 4
図 5: プログラム実行 4

図 5 ではレジスタに格納されたデータをメモリアドレス 116 番地へ出力しています。メインメモリは読み込むだけではなく、もちろん書き込むこともできますから、メモリアドレスを指定することによりメインメモリ上の特定の場所にデータを出力します。ここでこの例の処理は終わりとなっていますが、もしこれ以降も処理を続けることになったら、次に CPU は何を処理するでしょうか。難しそうに思えますが、基本を思い出してみてください。CPU は直前の命令であるメモリアドレス 112 番地の次のアドレスにあるデータを実行しようとします。しかし116 番地は命令ではなくデータです。CPU は命令でないデータを実行しようとしますからこれはエラーになります。

発展として

プログラムの流れ、CPU とメインメモリの間のデータのやりとりの大まかな様子を見てきました。しかし今見てきた例はたくさんの要素を省略して簡単に表したものです。また基本となる仕組みは共通ですが、CPU には様々な種類があり、それぞれできることが変わってきます。これらをより学ぶためにはアセンブリ言語を学ぶとよいでしょう。アセンブリ言語は今見てきたような命令を CPU に直接命令を出すことができます。