メモリとアドレス

前回、やったとおり、メモリとはいったんプログラムが読み込まれる装置です。
Windows等のマルチタスクのOSは複数のプログラムがメモリ上に存在します。

+---メモリ---+
|OSの領域    |
+------------+
|プログラム1 |
+------------+
|プログラム2 |
+------------+
|プログラム3 |
+------------+

メモリは1バイトごとの位置を表すためにアドレス(番地)という用語が使われます。
例えば下の図をご覧ください、あるプログラムの開始地点が1000番地とします。
実際に実行すると、1500番地、1501番地の値が共に 5 になります。

+--------+--メモリ----------+
|[番地]  | [内容]           |
+--------+------------------+
|0000    |   (略)           |
+〜〜〜〜+〜〜〜〜〜〜〜〜〜+
|1000    |相対アドレス      |
|        |500番地に5を代入  |
+--------+------------------+
|1001    |相対アドレス      |
|        |501番地に         |
|        |相対アドレス      |
|        |500番地の値を代入 |
+〜〜〜〜+〜〜〜〜〜〜〜〜〜+
|1500    |0                 |
+--------+------------------+
|1501    |0                 |
+--------+------------------+

コンピュータは1000番地の命令を実行し、次いで、1001番地の命令を実行します。
通常、プログラムはこのように、あるアドレスの命令を実行すると、次のアドレスの命令を実行します。
ただし、C言語で言うところの関数の呼び出しなどを行うと、次に命令を取り出すアドレスが前後に飛びます。

相対アドレス」という用語が使われていますが、
ここではプログラム開始の番地を0とした相対的なアドレスのことです。
そのプログラムの開始アドレス(上の場合1000番地)と相対アドレスを、
足す事によって絶対的なアドレスが出ます。
(上の場合「相対アドレス500番地」は「絶対アドレス1500番地」となる)

何故、そのような面倒なものを使うかというと、
プログラムがメモリのどの位置に読み込まれても、正しく実行できるためです。
(直接「1500番地のデータを書き換える」などという命令があった場合、
そのプログラムが2000番地に読み込まれた時に不具合=バグが出る)

上の例のプログラムをC言語で書くと次のようになります。
(ただし、上のアドレスと実際のアドレスは異なる)

int main()
{
  char x=0,y=0;
  x=5;
  y=x;

  /*以下略*/

  return 0;
}

難しそうに思えるC言語も、いちいち「何番地」と書かずに変数の名前で
データを扱えると思えば少しは簡単に思えてきますね。