リアルモードにおけるセグメントの制限
ここには私がこのプロジェクトにおけるCPUの制限をなぜ486以上にしたかという最大の理由が書かれています。

 まず、セグメント方式という物の説明をしましょう。セグメント方式とはメモリを区画割りする方式の一種です。 通常、プログラムがメモリを使用する場合、OSにメモリの一部を割り当ててもらう必要があります。 この時に割り当ててもらう区画の1つ1つを「セグメント」と呼びます。
 次に、8086のセグメントの問題点をいくつか挙げましょう。1つ目は、セグメント内のアドレスを16ビットで 管理しているため、大きさを64Kバイトより大きくすることができないのです。つまり、大きなメモリを確保した くてもできないというわけです。2つ目は、セグメントとセグメントの間に壁がないということです。これは、ある セグメントを管理しているプログラムが簡単に他のプログラムが管理しているセグメントにアクセスが (もちろん、書き込みも)できてしまうという大変な問題です。最悪、OSの管理下のメモリを破壊しパソコンを破壊 してしまう可能性もあります。さて、ここで1つ問題です。なぜこんな欠陥?だらけのシステムを採用してまで、8086 を出す必要があったのでしょうか?この答えは、8086が出た当初は、8ビットCPUからの移行が最重要課題だったからです。 また、当時のLSI技術で1チップにメモリの分離や保護といった機能を詰めることができなかったのも理由です。

このセグメントのメモリアドレスは下記の通りセグメントアドレスとオフセットアドレスとを加え合わせた数によって 指定します。このうち、セグメントアドレスはOSより割り当てられたセグメントの番号のことで要求してから 開放するまでずっと固定です。オフセットは、プログラム中でメモリにアクセスするために値を自由に増減させて利用する 番号です。 セグメントの先頭の物理アドレスの下位4ビットは常に0となるため、 セグメントは必ず16の倍数のアドレスから始まらなければならないということを頭に置いといてください。 下の例でいうと、セグメントアドレスである[1011 1001 0001 1101]を左に4シフトした数にオフセットアドレスの最小の 数である[0000 0000 0000 0000]を加え合わせた[1011 1001 0001 1101 0000]がセグメントの開始アドレス(セグメントベース) となります。
セグメントアドレス[B91D]
オフセットアドレス[0000]
    20                       0
    +----+----+----+----+----+
    |1011|1001|0001|1101|0000|
    +----+----+----+----+----+
    |セグメントアドレス  |    |
    +-------------------+    |
         |オフセットアドレス  |
         +-------------------+
ここで、問題点となるのが、20ビットで表せる範囲(1Mバイト)より大きなアドレスを「セグメントベース」 とするセグメントを扱うことはできないのです。たとえ、2Mバイトや4Mバイトといったメモリを搭載していても、 リアルモードでは1Mバイトまでしかアクセス することはできません。これが「1Mバイトの壁」です。
 また、オフセットアドレスも16ビットの値しか指定することはできません。つまり、セグメントの大きさは 最大でも64Kバイトまでとなります。これがいわゆる「64Kバイトの壁」です。
 問題は他にもあります。セグメントの大きさは64Kバイトまでですが、正確にいうとセグメントの大きさはすべて64Kバイトちょうどなのです。 つまり、32Kバイトや48Kバイトといった大きさのセグメントを理論的に考えることは可能なのですが、セグメントの大きさを任意に設定する 機構はハードウェア的には何も存在しないのです。
[48K][60K][32K]のメモリをOSから割り当ててもらった場合:

    +---+----------------------+---+---
    |   |                      |   |
    |48K|                      |   |48K
    |   |                      |   |
    +---+----+---+-------------+---+---
    |XXX|    |   |             |   |
    +---+    |   |             |   |
             |60K|             |   |60K
             |   |             |   |
             +---+----+---+----+---+---
             +---+    |   |    |   |
                      |32K|    |   |32K
                      +---+----+---+---
                      |XXX|    |   |
                      |XXX|    |   |
                      +---+    |   |
                               |   |
                              〜   〜
                              〜   〜
                               |   |
                               +---+
さて、この図を見てください。今、3つのプログラムが、それぞれこのようにメモリを宣言して、それぞれが メモリを確保した状態です。セグメントとは自由に値をいじれるオフセットアドレスが16ビットあるという 性質上、[XXX]の部分のメモリに簡単にアクセスできてしまうのです。ちなみにこの[XXX]の部分は他のプログラムが 使用しています。これが、大問題となるわけですね。

(2000/11/1)