主記憶體:配置、連結與分段

分段(segmentation)

想想你腦中如何自然地看待一個程式:「這裡是程式碼、這裡是待處理呼叫的堆疊、這裡是我配置資料的堆積、這裡是一張全域變數表。」你不會把它想成一條扁平的位元組緞帶;你以有意義、各自不同大小的部分來思考。分段是一種與這種觀點相符的記憶體方案:它讓程式的位址空間成為一群大小可變的段的集合,每個段是一個邏輯單元,像是程式碼、堆疊或堆積。

具體來說,在分段下,一個邏輯位址不是單一數字,而是一對:一個段號加上該段內的一個偏移。每個段可以是不同大小,並各自獨立地放置在實體記憶體中。要轉譯時,硬體用段號在段表裡查出該段的基底與界限,把偏移與界限相比(保護),再加上基底(重定位)以得出實體位址。所以段 2(比方說堆疊)可能住在某個實體基底、段 0(程式碼)住在另一個,各有自己的長度——而程式以「名稱加偏移」來定址每一個,而非以單一絕對位址。

為什麼重要:分段給出對程式設計者友善的、邏輯的記憶體觀點,並讓保護與共享變得自然——你可以把程式碼段標為唯讀且只可執行,或讓兩個行程共用一個段(共享程式庫)。它的弱點是段是大小可變的,所以在實體記憶體中配置它們會把外部碎裂帶回來,正如連續配置一般。這就是為什麼現代系統通常把分段與分頁結合:邏輯的、具名的段給出清晰的觀點,而對每個段分頁則消除外部碎裂。

一個程式有段 0 =程式碼(基底 1400、界限 1000)、段 1 =堆疊(基底 6300、界限 400)。邏輯位址 (1, 50) 表示段 1 內的偏移 50:檢查 50 < 400,然後實體 = 6300 + 50 = 6350。

一對 (段號, 偏移) 透過段表對應到一個實體位址。

分段反映程式的邏輯結構,但由於段的大小不一,它和連續配置一樣受外部碎裂之苦——這就是為什麼它通常與分頁搭配,而非單獨使用。

又稱
memory segmentation記憶體分段