正確な理解ができている気があまりしないのですが、とにかく全部読むことはできたので、自分なりに理解した内容をまとめてみようと思いました。
切り口としては、パイプラインが、とか、命令が、とかいろいろあるんだとは思うのですが、この本自体がOSと、CPUの連携について記述されている部分が多いため、OSから見たCPUの機能、という視点でまとめてみようと思います。
マルチタスク
486の背景には、OSがMS-DOSからWindowsへと、移行していく、という時代の流れがあったのだと感じます。
WindowsのようなマルチタスクOSに必要な機能をサポートすべく486には次の機能が実装されています(進化は286、386などいくつかの段階をへて、という感じだとは思いますが)。
- タスク管理機能
- セグメント機構
- アドレス変換
まず、マルチタスクOSというからには、まずタスク群をそれぞれ個別に管理するような機能が必要です。
次にタスクがアクセスするメモリ領域が重複しないようメモリの保護を行うことが重要になります。これを実現するのがセグメント機構です。
最後にマルチタスクを実現するためには広大なメモリ領域が必要になります。486ではアドレス変換機能を利用したページング処理により、メモリの物理的な限界を破る仮想記憶を実現します。
以下、それぞれの機能について説明します。
タスク管理機能
486では、タスク切り替えを1命令で実行可能です。
各タスクは(Task State Segment)というデータ形式(C言語的には構造体)で表現されます。
TSSは下記の情報を保存しています。
- 各レジスタの値
- OS用タスク管理情報
- I/O許可マップ
各種セグメントレジスタ、スタックポインタ、インストラクションポインタ、など、タスクごとに切り替える必要があるレジスタすべてを記憶しておく必要があります。
セグメント機構
- コードセグメント
- データセグメント
- スタックセグメント
コードセグメントとは、プログラム本体を配置するメモリ領域です。
いわゆる命令(インストラクション)のシーケンスを配置するためのものです。
現在実行されている命令はインストラクションポインタというレジスタで管理されます。
データセグメントとは、プログラムから扱うデータ(静的定数、静的変数、ヒープ領域など)を入れるメモリ領域です。
スタックセグメントは、スタックを配置するためのセグメントです。
スタックセグメント上のスタックの状態を管理するためにスタックポインタ、ベースポインタと呼ばれるレジスタが使用されます。
それぞれのコードセグメントはセグメントディスクリプタと呼ばれるテーブル構造で管理されます。セグメントディスクリプタにはセグメントのメモリ上の開始位置と、オフセットが設定されており、範囲を超えるとセグメンテーションフォルトという例外を発行します。
アドレス変換とページング
32bitのCPUならば約4GBのアドレス空間をあつかうことができますが、486当時のPCのメモリはそれには遠く及ばない物理メモリしか搭載してませんでした。
そこで論理アドレス(本文中ではリニアアドレスと呼ばれています)という抽象層を挟むことで、物理的な制約を飛び越えるアイデアが考案されました。
論理アドレスはその名の通り、論理的にとりうるすべてのアドレス空間上の位置をさします。
論理アドレスを使用すると、CPU側からは0から始まる広大なアドレス空間(論理アドレス空間)が見えます。
このCPUから見えるアドレス空間をページ単位に分割します。
例えばアドレス0x0〜0x0xFFまではページ1番、0x100〜0x1FFまではページ2番、という具合です。
次に実際の物理アドレス空間を論理アドレス空間と同じサイズで分割し、論理アドレス空間と、物理アドレス空間のページを1対1に対応づけます。この対応付けを管理するテーブルをページテーブルと呼び、この論理アドレスと物理アドレスの対応付けをアドレス変換、と呼びます。
ただ、このままでは若いアドレスの論理ページのみが物理メモリ上に存在することになり、すこぶる勝手が悪い状態です。
そこで、よく使うページを物理メモリ上に、あまり使わないページを外部記憶にクルクルと入れ替えながら使う、という仕組みで、どのメモリにアクセスしても同じような速度で使用できる、という仕組みが考えられました。この仕組みは、ページングを利用した仮想記憶、と呼ばれます。
余談ですが、このように使用頻度の高いメモリを、物理メモリの上にのせる、という話は、キャッシュの考え方そのものです。
現在使用中のメモリのそばに次に使うデータが配置されていることが多い、という性質を空間的局所性とよびます。また、最近使ったデータは再度使われることが多い、という性質を時間的局所性と呼びます。
キャッシュ、仮想記憶はこの時間的、空間的局所性を利用して、広大なメモリ空間を表現する仕組みです。
結び
本の中では8086+MS-DOSと、i486+マルチタスク、という対比で説明されていることが多かったです。i486の時代はまさしくマルチタスクがPCで、ということが現実味を帯びてきた時代だったのだと思います。
けっして現在廃れてしまった話ではなく、むしろ基本となる話だと思いますので、この本を読んで本当によかったと思います。
拙文を最後までお読みいただきありがとうございました。