コンピューターの基本構成は図1に示したとおりであるが, 制御装置と演算装置,記憶装置,入力装置, 出力装置を五大装置と呼ぶ.それぞれは,次のような働きがある.
主記憶装置(メインメモリー)は略して,メモリーと呼ばれることが多い.この講義でもメ モリーといえば,主記憶装置(メインメモリー)を指す.パソコンの広告を見ると「メモリー 512Mbyte搭載」とか書いてある.これがまさにメモリーの大きさを示している.
これらのなかで,制御装置と演算装置をまとめて中央制御装置(CPU:Central Processing Unit)と言う.とくに,これらを一つのチップにまとめたものを MPU(Micro Processing Unit) と言う.Intel社のPentiumやAMD社のAthlon,IBM社のPowerPCなどがMPUである.世 間一般ではMPUとCPUはほとんど同義語として使われるので,本講義では全てCPUに統一す る.その方が諸君もなじみ深いであろう.
図1では,入力装置と出力装置は分けたが,ひとつで2つの機 能を果たすものもある.例えば,LANカードがそれにあたる.
プログラマーは,メモリーの内容をある程度自由に変更ができる.そのようなこと から,メモリーを意識してプログラムを作成することが重要である.アセンブラー言語を使うと なるとCPUについても意識が必要であろうが,C言語ではそこまで要求しない.諸君は,メ モリーを意識しろ!!!
メインメモリーの役割は,命令とデータからなるプログラムを記憶することである.記憶 する内容は,0と1のビットパターンのみである.なぜならば,プログラムは全て,0と1の 数字で表せ,二進数で表現可能であるからである.コンピューター内部では,データも命 令も全て0と1の二進数で表現している.命令も二進数である;どうだ,驚いたか.ここで は,この二進数のビットパターンを格納するメモリーについて学習する.
プログラムという情報は記憶するだけでは全く役に立たない.記憶した内容を取り出せて 初めて,活用ができる.また,格納できる情報がひとつでは全く役に立たない.多くの情 報が格納でき,必要なときにいつでも取り出すことができる装置がメモリーである.
メモリーは大量の情報を格納し,その中の任意の情報を取り出すことができる.そのため に,メモリーには記憶する場所毎に住所が決められている.この住所のことをアドレス (address)と言い,整数の番地がふってある.諸君が使っているパソコンのアドレス は32ビットで表現されている3.そして,一つの番地には,8個の0と1が記憶できる.この様子を図 3に示す.
図を見て分かるとおり,2進数の表現は桁数が多くて人間にとって大変である4.そこで,通常は,2進数の4桁をまとめて,16進数で 表す.そうすると,アドレスは16進数8桁,記憶内容は16進数2桁で表すことができ,分か りやすくなる.その様子を図4に示す.
ついでに述べておくが,1個の0あるいは1の情報量を1ビットと言う.8ビットで1バイトと 言う.従って,メインメモリーの一つの番地(アドレス)には,1バイト(8ビット)の情報が 記憶できる.
メモリーについて覚えておくことは,以下の通りである.
ところで,CPUは,どのようにしてメモリーに情報を書き込んだりメモリーから情報を読み込んだり するのだろうか? 簡単にその仕組みを説明するので,図2 のアドレスバスとデータバスを見よ5.CPUは読み書きを行いたいアドレスをアドレスバス の電圧を使って,メモリーに知らせる.32本のアドレスバスの電圧をhigh--1の状態-- とlow--0--の状態にすることにより,32ビットのアドレスを指定する.すると,8本の データバスをとおして,データが流れるのである.読み込み/書き込みの区別は,CPUが制 御線の電圧で決め,それに応じてメモリーが動作する.
付録のリスト4にデータ型のバイト数を調べるプログラムを載せておく.
double x=-7.696151733398438e-4; int i=55; char a='a';
鋭い学生は,データの並びが逆であることが分かるであろう.例えば,整数のiであ るが, なので, と並ぶと考えるだろうが,実際は図 5のように逆に並ぶ.これはCPUがそのように作ら れているからである.このように逆に配置させる方法をリトルエンディアンと 言う.Intel社のCPUはリトルエンディアンである.一方,そのままのメモリーに配置する 方法はビッグエンディアンと呼ばれる.ここで述べたように,メモリーにデー タを並べる方法は2通りあって,それをバイトオーダーと言う.どちらがより良いかは分 からない.
ここで,理解しておくべきことは,以下の通りである.
それでは,リスト1に示す簡単なプログラムで,データとメモリー の格納アドレスを調べてみよう.このプログラムの各行の動作は,以下の通りである.まだ,詳 細は分からなくても良いが,大体の流れをつかんで欲しい. -4pt
1 #include <stdio.h> 2 int func(int i, int j); 3 4 /*======================================================*/ 5 /* メイン関数 */ 6 /*======================================================*/ 7 int main(void) 8 { 9 int i; 10 11 printf("--- address -----------\n"); 12 printf("\tmain\t%p\n", main); 13 printf("\tfunc\t%p\n", func); 14 printf("\tmain-i\t%p\n",&i); 15 16 i=func(5,3); 17 18 return 0; 19 } 20 /*======================================================*/ 21 /* func 関数 */ 22 /*======================================================*/ 23 int func(int i, int j) 24 { 25 26 printf("\tfunc-i\t%p\n",&i); 27 printf("\tfunc-j\t%p\n",&j); 28 29 return i*j; 30 }
--- address ----------- main 0x8048368 func 0x80483eb main-i 0xbffff6b4 func-i 0xbffff690 func-j 0xbffff694
実行結果から,命令とデータは図6のようになっ ていることが分かるであろう.命令である関数は,大体近くのメモリの先頭付近に配置さ れている.しかし,データの内容を格納する変数は,ずっと離れてメモリーの後ろの方に 割り当てられている.
関数の中で宣言される変数は,ローカル変数と言い,その宣言した関数でのみアクセスが 可能である.従って,同じ名前であるが,違う関数で宣言されたローカル変数は全く別物であ る.図6で分かるように,関数mainと関数 funcで同じ名前のローカル変数 i を宣言してるがメモリー上の配置は全く異 なる.このことからも,名前は同じであるが,全く違うものであることが理解できる.
ここで,理解しておくべきことは,以下の通りである.