x86 架構中，記憶體區段是在不改變 16 位元段選擇子時，使用單個索引暫存器（儲存了段內地址偏移值）所能夠定址的的記憶體範圍部份。也指在英特爾 x86 指令集體系結構下記憶體區段的實現方式。 從 8086 開始到隨後的各款 x86 架構 CPU，無論是真實模式還是保護模式，記憶體定址時都使用 16 位段暫存器（segment register）。段暫存器預設使用情況為： 程式碼段暫存器 CS 與暫存器 IP 相配合獲得當前執行緒程式碼執行到的記憶體位置； 資料段暫存器 DS 與各通用暫存器配合訪問記憶體中的資料； 棧段暫存器 SS 與暫存器 E SP、E BP 配合訪問執行緒的呼叫棧（call stack）； 擴充套件段暫存器 ES 用於特定字串指令（如 MOVS 或 CMPS）。 80386 引入了 2 個額外的段暫存器 FS 與 GS，並無特定的硬體用途。 這些段暫存器除了有 16 位的可見部分，還有不可見的隱藏部分，稱為描述符快取 descriptor cache 或隱藏暫存器 shadow registerIntel 64 and IA32 Architectures Software Developers Manual Volume 3 System Programming Guide published in 2011 Page Vol 3A 311。當一個段選擇符（segment selector）裝入段暫存器的可見部分，處理器同時也把該段描述符的其它資料裝入到段暫存器的隱藏部分，這包括段開始的基地址、段長度、訪問控制資訊等。這些資訊快取到段暫存器中，避免了處理器在轉址（translate address）時花費額外的匯流排週期從段選擇符表中讀入資料。處理器指令中可以明示使用哪些段暫存器，這將替換掉預設使用的段暫存器。Intel Corporation 2004 IA32 Intel Architecture Software Developers Manual Volume 1 Basic Architecture 歷史 1978 年的 Intel 8086 開始引入了記憶體分段。這使得 16 位 CPU 可以訪問超過 64 KB 65536 位元組 的記憶體，實際上 8086 CPU 到記憶體的地址匯流排是 20 位，即可訪問 2201MB 記憶體。在 16 位元模式，要讓應用程式使用多個記憶體區段（為了存取比任一 64K 區段還要大的記憶體）是相當複雜。這個問題的根源在於沒有適當的適合做整個記憶體範圍的平面定址的位址算術指令。平面定址方式也可以乘法指令來完成，但這會導致較慢的程式執行速度。 1982 年面世的 80286 處理器的真真實模式與保護模式，以及 80386 及其後的處理器的虛擬 86 模式，一個區段的大小是 64 KiB（使用 16 位元索引暫存器）。在 Intelx86 的真真實模式下的區段架構的記憶體空間會有所重疊，這是一種不好的設計。 80286 的保護模式下，16 位的段暫存器中的 13 位（稱作段選擇符 segment selector）是描述符表的條目（descriptor table entry）的索引；該條目包含了 24 位的段開始地址以及 16 位的段長度；段開始地址與段內偏移地址相加即為記憶體物理地址。16 位段暫存器中的剩餘 3 位分別是全域性 區域性描述符表指示位、請求特權級（request privilege level）。 1985 年面世的 80386 及其後續處理器的 32 位元保護模式下，一個區段長度上限是 220 個粒度單位，粒度可以是 1 位元組或 4K 位元組，因此分段長度上限可以是 4 GB，這與索引暫存器是 32 位元相配合。 隨著 32 位元作業系統的推出，以及更舒適的 32 位元平面記憶體模式，到 1990 年末期幾乎淘汰了使用區段定址。然而，使用 32 位平面記憶體模式產生的最多隻能訪問 4 GB 地址空間的限制並沒有遠離日常的使用。區段允許作業系統對每個行程虛擬定址空間的限制，最大可利用 64 GB 的系統記憶體，但這種最終回歸到區段的尷尬，經常被引述為朝著 64 位元處理器發展的動機。 2003 年問世的 x8664 架構下，強制實現了平面記憶體模式，但保留了使用段暫存器 FS 或 GS 的 64 位下的分段定址。 真實模式 （Real Mode） 真實模式與虛擬 86 模式下，可訪問記憶體固定為 1 MB。對於 8086 處理器，可使用暫存器長度為 16 位元組，但是擁有 20 位元組的到記憶體匯流排地址。為了使用 16 位元組暫存器訪問 20 位元組地址，整個記憶體被劃分為多個區段。一個區段長 65536 位元組即 64 KB。在真實模式下，訪問記憶體必須透過 segment base address 和 segment offset 分別儲存在任意 segment 暫存器和任意通用暫存器裡。 真實訪問的物理地址可由以下公式得到： 物理地址 （segment base address0x10 segment offset 注意同樣的物理地址可以由多個不同對的 selector，offset 組成。 真實模式下，任何程式都可以訪問全部記憶體空間。沒有對記憶體的訪問許可權保護。 80286 保護模式 Intel 80286 處理器仍然使用 16 位段暫存器與 16 位的段內偏移地址，但保護模式下支援訪問 224（16M）位元組的記憶體。16 位段暫存器內不再是段地址，16 位段暫存器的高 13 位被稱作段選擇符（segment selector），其值是到表的索引值。段描述符中包含了 24 位的段開始的基地址，20 位的段長度。段開始地址與段內偏移地址相加即為記憶體物理地址。段的長度上限為 2201M 位元組。 80386 保護模式 Intel 80386 處理器繼續使用 286 的分段保護模式，但段描述符中包含了 32 位的段開始的基地址。段內偏移地址也是 32 位。在分段轉址與物理地址之間又增加了一層分頁（paging）轉址。分段定址是不能關閉的。分頁可以開啟或關閉（enabled or disabled），如果關閉就與 286 保護模式一樣。如果使用分頁機制，則由段開始的基地址與段內偏移地址相加得到的是線性地址（虛地址），線性地址還需要分頁轉址才得到記憶體物理地址。 386 的段描述符中的段長度為 20 位，段長度的粒度可設為 1 位元組或 212 位元組。因此段長度可以為 1 位元組 1M 位元組，或者為 14K 位元組 1M4K 位元組。段描述符的資料結構為； B Bits 80286 80386 B 0 0007 07 limit bits 015 of limit 0 1 0815 07 limit bits 015 of limit 1 2 1623 07 base address bits 023 of base address 2 3 2431 07 base address bits 023 of base address 3 4 3239 07 base address bits 023 of base address 4 5 4047 07 attribute flags 1 attribute flags 1 5 6 4851 03 unused bits 1619 of limit 6 6 5255 47 unused attribute flags 2 6 7 5663 07 unused bits 2431 of base address 7 Attribute flags 2 52 4 unused available for operating system 53 5 reserved should be zero 54 6 default flag Dbit 55 7 granularity flag Gbit Byte offset inside entry First range is the bit offset inside entry second range is the bit offset inside byte 386 處理器增加了兩個段暫存器 FS、GS，這兩個暫存器並無硬體繫結的用途。Windows 作業系統在地址 FS0 中儲存了當前執行緒資訊塊。Linux 中 GS 指向了執行緒區域性儲存。 透過清除控制暫存器 CR0 中的最低位，可由 386 保護模式轉為真實模式。 Linux 作業系統在 386 保護模式下把段基址設為 0，段長度設為 4GiB，從而模擬了平面記憶體模型。 段暫存器名字 描述 基地址 段長度 段描述符特權級 __KERNEL_CS 核心程式碼段 0 4 GiB 0 __KERNEL_DS 核心資料段 0 4 GiB 0 __USER_CS 使用者程式碼段 0 4 GiB 3 __USER_DS 使用者資料段 0 4 GiB 3 x8664 的 64 位模式 在 x8664 體系結構 64 位的 long mode，段暫存器 CS SS DS ES 強制為 0。段長度強制為 264。形式上還有記憶體分段，但實際上所有記憶體都在唯一的一個分段中。段暫存器 FS、GS 可以有非 0 值，被作業系統用於其它用途。即硬體支援如 FSRAX 這樣的暫存器間接定址。 參考文獻 CategoryX86 記憶體管理