計算機管理內存的基本方式有兩種:段式管理和頁式管理。而在使用80x86微處理器時,內存地址分爲三個不一樣的地址:邏輯地址,線性地址,物理地址。他們之間有什麼關係,內存是如何尋址,本文主要介紹的就是內存尋址。html
一、基本概念:linux
cpu段式管理:段式管理的基本原理是指把一個程序分紅若干個段(segment)進行存儲,每一個段都是一個邏輯實體(logical entity)。一個用戶做業或進程所包含的段對應一個二維線形虛擬空間,程序經過分段(segmentation)劃分爲多個模塊,故能夠對程序的各個模塊分別編寫和編譯。段式管理程序以段爲單位分配內存,而後經過地址影射機構把段式虛擬地址轉換爲虛擬地址。數組
cpu頁式管理: 頁式管理的基本原理將各進程的虛擬空間劃分紅若干個長度相等的頁(通常爲4K),頁式管理把內存空間按頁的大小劃分紅片或者頁面(page frame),而後把頁式虛擬地址與內存地址創建一一對應頁表,並用相應的硬件地址變換機構,來解決離散地址變換問題。數據結構
邏輯地址:包含在機器語言指令中用來指定一個操做數或一條指令的地址,每一個邏輯地址都由一個段和偏移量組成,表示爲[段標識符:段內偏移量]。例如,在C/C++程序中咱們使用指針對變量地址操做,該地址就是邏輯地址(準確的應該說是邏輯地址的段內偏移量)。對應上述段式管理,邏輯地址是段式管理轉換前的程序地址。spa
線性地址:也稱爲虛擬地址,它是一個32位無符號整數,故能夠用來表達高達4GB的地址。線性地址同邏輯地址同樣也是不真實的地址。對應上述頁式管理,線性地址是頁式管理轉換前的地址。操作系統
物理地址:用於內存芯片級內存單元尋址,與處理器和CPU鏈接的地址總線相對應。通常狀況下,咱們說的計算機內存條中的內存就是它(雖然不許確)。.net
有了上述的基本概念後,很顯然,CPU將一個虛擬內存空間中的地址轉換爲物理地址,須要進行兩步:首先將給定一個邏輯地址,CPU要利用其段式內存管理單元,先將每一個邏輯地址轉換成一個線程地址,再利用其頁式內存管理單元,轉換爲最終物理地址。這就是咱們所知道的段頁式管理,這樣兩次轉換的好處能夠克服段式管理和頁式管理的缺點。線程
二、CPU段式內存管理:邏輯地址轉換爲線性地址unix
邏輯地址由兩部分組成:一個段標識符和一個指定段內相對地址的偏移量(簡稱偏移量),[段標識符: 段內偏移量]。指針
段標識符是由一個16位長的字段組成,稱爲段選擇符,由處理器提供段寄存器來存放段標識符,段寄存器有6種:
(1)cs 代碼段寄存器,指向包含程序指令的段;
(2)ss 棧寄存器,指向包含當前程序的段;
(3)ds 數據段寄存器,指向包含靜態數據或者全局數據段;
(4)其餘三個寄存器es, fs, gs稱爲附加段寄存器,做通常用途,能夠指向任意的數據段。
偏移量指明瞭從段開始的地方到實際地址之間的距離,偏移量爲32位。
如上圖爲段標識符(段選擇符)格式,其中最關鍵的部分爲索引號。
段標識符,按照其字面意思即可理解它的做用是用來標識一個段的,而段是如何表示的呢?
這就引伸到了另一個概念:段描述符,每一個段由一個8字節的段描述符表示,它描述了段的特徵(段描述符就是段)。段標識符經過索引號(13位)就能夠找到其對應的段(段描述符),段的格式以下圖所示:
段描述符中咱們須要關注的字段爲:Base,它描述了一個段的開始位置的線性地址。
段描述符放在全局描述符表(GDT,存放於gdtr寄存器中)或局部描述符表(LDT,存放於ldtr寄存器中)中,一般只定義一個GDT,而每一個進程除了存放在GDT中的段以外若是還學要建立附加的段,就能夠有本身的LDT。。
好了,經過上述的講解,咱們就能夠關注一個邏輯地址是怎樣轉化成相應的線性地址的,具體步驟以下:
(1)先檢查邏輯地址的段選擇符的TI字段,以決定段描述符保存在哪個描述符表中。(TI=0代表在GDT中,TI=1代表存在LDT中)
(2)根據段選擇符的索引號,計算查找段描述符的地址,方法:索引號*8 + gdtr或者ldtr寄存器中的內容 = Base。
(3)把邏輯地址的偏移量與步驟(2)中獲得的Base字段值相加就能夠獲得其對應的線性地址。
邏輯地址的轉換圖以下圖所示:
三、CPU頁式內存管理:線性地址轉換爲物理地址
首先,咱們得知道一些線性地址相關的東西。
(1)線性地址被分紅固定長度爲單位的組,稱爲頁。頁內部連續的線性地址被映射到連續的物理地址中。
(2)分頁段元把全部的物理地址分紅固定長度的頁框,稱爲物理頁。
(3)線性地址映射到物理地址的數據結構稱爲頁表。
(4)32位的線性地址,被分紅3個域:目錄(Directory)高10位,頁表(Table)中間10位,偏移量(Offset)低12位,由偏移量的12bit可知,每頁含有4096字節的數據。
線性地址的轉換分兩步完成,每一步都基於一種都基於一種轉換表,第一種轉換表稱爲頁目錄錶轉換,第二種轉換稱爲頁錶轉換。使用這種二級模式的目的在於減小每一個進程頁表所需的RAM的數量。就像咱們看書有個書目錄同樣,方便快捷。具體轉換以下圖所示:
轉換步驟:
(1)從cr3中取出進程的頁目錄地址(操做系統負責在調度進程的時候,把這個地址裝入對應寄存器);
(2)根據線性地址前十位,在數組中,找到對應的索引項,由於引入了二級管理模式,頁目錄中的項,再也不是頁的地址,而是一個頁表的地址。(又引入了一個數組),頁的地址被放到頁表中去了。
(3)根據線性地址的中間十位,在頁表(也是數組)中找到頁的起始地址;
(4)將頁的起始地址與線性地址中最後12位相加,獲得最終咱們想要的其對應的物理地址。
參考:
(1)深刻理解linux內核