メモリ分割とは、オペレーティングシステムにおけるメモリ管理手法の一つで、コンピュータの主記憶装置をセグメントまたはセクションに分割するものです。分割方式を採用しているコンピュータシステムでは、メモリ位置への参照には、セグメントを識別する値と、そのセグメント内のオフセット(メモリ位置)が含まれます。セグメントまたはセクションは、コンパイル済みプログラムのオブジェクトファイルがプログラムイメージにリンクされる際、およびそのイメージがメモリにロードされる際にも使用されます。
セグメントは通常、個々のルーチンやデータ テーブルなどのプログラムの自然な区分に対応します[ 1 ]。そのため、セグメンテーションは一般的にページングのみよりもプログラマにとって分かりやすいです。[ 2 ]セグメントは、プログラムモジュール、またはコード セグメントやデータ セグメントなどのメモリ使用のクラス用に作成できます。[ 3 ]特定のセグメントは、プログラム間で共有される場合があります。[ 1 ] [ 2 ]
セグメンテーションはもともと、システムソフトウェアがソフトウェアプロセス(タスク)とそれらが使用するデータを分離する方法として考案されました。これは、複数のプロセスを同時に実行するシステムの信頼性を向上させることを目的としていました。[ 4 ]
セグメンテーションを使用するシステムでは、コンピュータのメモリ アドレスはセグメント ID とセグメント内のオフセットで構成されます。[ 3 ]ハードウェアメモリ管理ユニット(MMU) は、セグメントとオフセットを物理アドレスに変換し、変換が可能であること、およびそのセグメントとオフセットへの参照が許可されていることを確認するためのチェックを実行します。
各セグメントには、長さと一連の権限(読み取り、書き込み、実行など)が関連付けられています。[ 3 ]プロセスは、参照の種類が権限によって許可され、セグメント内のオフセットがセグメントの長さによって指定された範囲内にある場合にのみ、セグメントへの参照を行うことができます。そうでない場合は、セグメンテーション違反などのハードウェア例外が発生します。
セグメントは仮想メモリの実装にも使用できます。この場合、各セグメントには、メインメモリに存在するかどうかを示すフラグが関連付けられています。メインメモリに存在しないセグメントにアクセスしようとすると、「セグメントが存在しません」という例外が発生し、オペレーティングシステムは二次記憶装置からそのセグメントをメモリに読み込みます。
セグメンテーションはメモリ保護を実現する方法の一つです。[ 5 ]ページングもその一つで、これらは組み合わせることができます。メモリセグメントのサイズは一般的に固定されておらず、最小で1バイトになることもあります。[ 6 ]
セグメンテーションは、ページングの有無にかかわらず、さまざまなハードウェア上で複数の方法で実装されてきました。Intel x86のメモリセグメンテーションはどちらのモデルにも当てはまらないため、以下で別途説明するとともに、別の記事でより詳細に解説します。
各セグメントには、そのセグメントがメモリ内のどこにあるかを示す情報(セグメントベース)が関連付けられています。プログラムがメモリ位置を参照する際、オフセットがセグメントベースに加算されて物理メモリアドレスが生成されます。
ページングを用いないセグメンテーション方式で仮想メモリを実装する場合、メインメモリと二次記憶装置の間でセグメント全体をスワップインする必要があります。セグメントがスワップインされる際、オペレーティングシステムはセグメント全体を格納するのに十分な連続した空きメモリ領域を確保しなければなりません。メモリの総量は十分であっても、連続した空きメモリ領域が不足すると、メモリ断片化が発生することがよくあります。
セグメント情報には、メモリ位置の代わりに、そのセグメントのページテーブルのアドレスが含まれます。プログラムがメモリ位置を参照する場合、オフセットはページテーブルを使用してメモリアドレスに変換されます。セグメントは、別のメモリページを割り当ててセグメントのページテーブルに追加することで拡張できます。
ページングを伴うセグメンテーションを使用するシステムにおける仮想メモリの実装では、通常、ページング方式の非セグメント化システムと同様に、個々のページをメインメモリと二次記憶装置の間で往復させるだけです。セグメント内のページはメインメモリ内のどこにでも配置でき、連続している必要はありません。これにより、通常、メインメモリと二次記憶装置間の入出力量が減り、メモリの断片化が軽減されます。
The Burroughs CorporationB5000 computer was one of the first to implement segmentation, and "perhaps the first commercial computer to provide virtual memory"[7] based on segmentation. The B5000 is equipped with a segment information table called the Program Reference Table (PRT) which is used to indicate whether the corresponding segment resides in the main memory, to maintain the base address and the size of the segment.[8] The later B6500 computer also implemented segmentation; a version of its architecture is still in use today on the Unisys ClearPath Libra servers.
The GE 645 computer, a modification of the GE-635 with segmentation and paging support added, was designed in 1964 to support Multics.
The Intel iAPX 432,[9] begun in 1975, attempted to implement a true segmented architecture with memory protection on a microprocessor.
The 960MX version of the Intel i960 processors supported load and store instructions with the source or destination being an "access descriptor" for an object, and an offset into the object, with the access descriptor being in a 32-bit register and with the offset computed from a base offset in the next register and from an additional offset and, optionally, an index register specified in the instruction. An access descriptor contains permission bits and a 26-bit object index; the object index is an index into a table of object descriptors, giving an object type, an object length, and a physical address for the object's data, a page table for the object, or the top-level page table for a two-level page table for the object, depending on the object type.[10]
Prime, Stratus, Apollo, IBM System/38, and IBM AS/400 (including IBM i) computers use memory segmentation.
Burroughs introduced segmentation on the B5000, followed by the compatible B5500 and B5700.
The later B6500 replaced the Program Reference Table (PRT) with a Saguaro stack, changed control word formats, changed descriptor formats and changed the mechanism for referring to a control word or descriptor.
B5000、B5500、B5700のワードは48ビット長です。[ 11 ]ディスクリプタはワードの最上位ビットがセットされています。ディスクリプタはプログラム参照テーブル(PRT)またはスタックに存在し、データがメモリに存在するかどうかを示す存在ビットを含んでいます。データディスクリプタとプログラムディスクリプタは別々です。[ 11 ] : 4-2-4-4
B6500 とその後継機種のワードは、48 ビットのデータと 3 ビットのタグビットを持ちます。[12]:2-1タグビットは、ワードに含まれるデータの種類を示します。異なるタグビット値によって示される記述子の種類がいくつかあります。[ 12 ] : 6-5–6-10制御ワードと記述子は Saguaro スタックに格納されます。配列セグメントはページングされる場合があります。
このシリーズには、B6500、B6700、B7700、B6800、B6900、B5900、BurroughsおよびUnisysのAシリーズマシン、そして現在のClearpath MCPシステム(Libra)が含まれます。長年にわたって、特にハードウェアの進歩など、いくつかの機能強化が行われてきましたが、アーキテクチャはほとんど変わっていません。セグメンテーション方式は同じままです(セグメントメモリを参照)。
IBM System/370モデル[ a ]では、仮想ストレージ[ 13 ] [ 14 ] (DAT) と 24 ビット アドレスを使用しており、制御レジスタ0 はセグメント サイズを 64 KiB または 1 MiB、ページ サイズを 2 KiB または 4 KiB のいずれかに指定します。制御レジスタ 1 にはセグメント テーブル指定子 (STD) が含まれており、セグメント テーブルの長さと実際のアドレスを指定します。各セグメント テーブル エントリには、ページ テーブルの位置、ページ テーブルの長さ、および無効ビットが含まれています。IBM は後にアドレス サイズを 31 ビットに拡張し、セグメント テーブル エントリに 2 ビットを追加しました。
IBMのDAT実装にはそれぞれ、変換キャッシュが含まれており、IBMはこのキャッシュを変換ルックアサイドバッファ(TLB)と呼んでいます。『動作原理』ではTLBについて概説していますが、詳細はアーキテクチャの一部ではなく、モデルごとに異なります。
IBMは、 3031、3032、3033プロセッサ複合体から、デュアルアドレス空間[ 14 ] : 5-13–5-17、デュアルアドレス空間制御: 5-17–5-20、DAS認証メカニズム: 5-21–5-24、PC番号変換[ 15 ] (DAS)と呼ばれる機能を提供しました。この機能により、プログラムはプライマリアドレス空間(CR1)とセカンダリアドレス空間(CR7)と呼ばれる2つのアドレス空間の変換テーブルを切り替え、保護キーに従ってアドレス空間間でデータを移動できます。DASは、16ビットアドレス空間番号(ASN)をSTDに変換する変換テーブルをサポートし、特権命令を使用してSTDをCR1(プライマリ)またはCR7(セカンダリ)にロードします。
Intel 8086から始まる初期のx86プロセッサは、粗雑なメモリ分割とメモリ保護機能を持たない(各セグメントのすべてのバイトが常にどのプログラムでも使用可能) 。16 ビットのセグメント レジスタにより 65,536 個のセグメントが使用可能。各セグメントは、セグメント番号の 16 倍に等しい固定オフセットから開始。セグメントの開始アドレスの粒度は 16 バイト。各セグメントは、64 KiB (65,536 バイト) のアドレス空間への読み書きアクセスを許可(この制限は 16 ビットの PC レジスタと SP レジスタによって設定され、プロセッサは境界チェックを行わない)。オフセット + アドレスが 0xFFFFF を超えると、0x00000 にラップアラウンドする。各 64 KiB セグメントは次の 4,095 個のセグメントとオーバーラップし、各物理アドレスは 4,096 組のセグメント - オフセットで表すことができる。この方式では、1 MiB (1024 KiB) の物理メモリ (およびメモリ マップド I/O)しかアドレス指定できない。 (オプションの拡張メモリハードウェアにより、ソフトウェア制御でバンク切り替えメモリを追加できます。)インテルは、これらのx86 CPUモデルの唯一の動作モードを後付けで「リアルモード」と名付けました。
Intel 80286以降のプロセッサでは、「286プロテクトモード」が追加され、16ビットアドレッシングが維持され、セグメンテーション(ページングなし)とセグメントごとのメモリ保護が追加されます。下位互換性のために、すべてのx86 CPUは「リアルモード」で起動し、同じ固定の重複する64 KiBセグメント、メモリ保護なし、1 MiBの物理アドレス空間のみ、およびいくつかの微妙な違い(高メモリ領域、非リアルモード)があります。80286以降のプロセッサは、24ビット(16 MiB)の物理アドレス空間と高度なMMU機能を使用するために、通常はオペレーティングシステムまたはDOSエクステンダーなどのソフトウェアによって「プロテクトモード」に切り替える必要があります。プログラムがセグメントレジスタを使用しない場合、またはオペレーティングシステムから受け取った値のみをセグメントレジスタに格納する場合は、同じコードをリアルモードまたはプロテクトモードで実行できますが、ほとんどのリアルモードソフトウェアはセグメントレジスタの新しい値を計算するため、この互換性が失われます。
Intel i386以降のプロセッサでは、「386保護モード」が追加され、32ビットアドレッシングを使用し、セグメンテーションを維持し、メモリページングが追加されます。これらのプロセッサでは、セグメントテーブルは、セグメントのページテーブルを指すのではなく、リニアメモリ内のセグメントアドレスを保持します。ページングが有効になると、リニアメモリ内のアドレスは、別のページテーブルを使用して物理アドレスにマッピングされます。ほとんどのオペレーティングシステムはセグメンテーション機能を使用せず、すべてのセグメントレジスタのベースアドレスを常に0に維持し、ページングのみを使用してページごとのメモリ保護とスワッピングを提供することを選択しました。一部のシステムは、NXビットを持たないプロセッサで実行可能領域保護を提供するためにCSレジスタを使用したり、スレッドローカルストレージにアクセスするためにFSレジスタまたはGSレジスタを使用したりします。[ 16 ] [ 17 ]
x86-64アーキテクチャは「ロング モード」(64 ビット モード)でのセグメンテーションをサポートしていません。 [ 18 ]セグメント レジスタ CS、SS、DS、ES の 4 つは 0 に強制され、制限は 2 64になります。セグメント レジスタ FS と GS は、ゼロ以外のベース アドレスを持つことができます。これにより、オペレーティングシステムは、スレッド ローカル ストレージなどの特別な目的でこれらのセグメントを使用できます。[ 16 ] [ 17 ]