認識各種記憶體位址

2021-10-06 19:44:44 字數 2935 閱讀 3080

實體地址就是記憶體單元的絕對位址,實體地址0x0000就表示記憶體條的第乙個儲存單元,0x0010(16進製制)就表示記憶體條的第17個儲存單元,乙個儲存單元是1byte(8bit)。

你問為什麼是1byte?

乙個記憶體條是由若干個黑色的記憶體顆粒構成的。每乙個記憶體顆粒叫做乙個chip。

每個chip中又疊了若**ank

在每個bank內部,就是電容的行列矩陣結構了,每乙個元素有8個小電容,儲存8個bit,也就是乙個位元組。

在80286系列以前,cpu只支援實模式操作模式。16位暫存器想要對20位位址線進行定址,使用分段機制,段基址(16位) x 16(左移4位) + 段內偏移位址(4位)就是實體地址了。

這樣的好處是所見即所得,程式設計師指定的位址就是實體地址,實體地址對程式設計師是可見的。同時也帶來了一些問題:

1) 無法支援多工。

2) 程式的安全性無法得到保證。

(根本原因就是乙個程式直接修改了其他程式的記憶體,導致崩潰)

80286系列則是被設計來解決這些問題,段式訪存得到的改進,原來段基址+段內偏移得到的位址不再是實際的實體地址,而是被稱作為線性位址,要經過乙個轉換層轉換才變成乙個實體地址。這種cpu操作模式就被稱為保護模式了。保護的是:分清楚各個程式使用的儲存區域,不允許隨便跨界訪問。

保護模式雖然解決了記憶體不被跨界訪問,但是其也帶來了新的問題,那就是記憶體碎片。

首先我們了解一下記憶體碎片為何產生:

首先假設我們有10b記憶體:

id首位址

尾位址長度狀態0

0910空閒

當程式申請乙個長度為3的記憶體空間後:

id首位址

尾位址長度狀態0

0231

397空閒

當程式再申請乙個長度為2,以及長度為4的記憶體空間後:

id首位址

尾位址長度狀態0

0231

3422

5843

991空閒

此時,只剩1個可用空間。如果這時程式再來申請長度大於1的空間,就申請不了,也就是記憶體不夠。

現在,釋放掉id=1的空間:

id首位址

尾位址長度狀態0

0231

342空閒

2584

3991

空閒我們發現,現在可用記憶體空間為3,但是,這3個空閒空間,並不是連續的。

所以,如果程式現在申請長度為3的記憶體空間,同樣會申請不了,會出現記憶體不夠。我們把這種情況,稱之為記憶體碎片。

那記憶體碎片怎麼解決呢?於是就有了分頁機制,接下來我們詳細講一下分頁:

首先,把物理記憶體,按照某種尺寸,進行平均分割。比如我現在以2個記憶體單位,來分割記憶體,也就是每兩個連續的記憶體空間,組成乙個記憶體頁:

位址頁id狀態0

0空閒12

1空閒34

2空閒56

3空閒78

4空閒9 接著,系統同樣需要維護乙個記憶體資訊表:

id使用的記憶體頁id

現在,程式申請長度為3的記憶體空間,不過由於現在申請的最小單位為頁面,而乙個頁面的長度為2,因此現在需要申請2個頁面,也就是4個記憶體空間。你看,這就浪費了1個記憶體空間。

位址頁id狀態0

0121

342空閒

563空閒

784空閒

9 id使用的記憶體頁id

00,1

接著,程式再申請長度為1,長度為2的空間:

位址頁id狀態0

0121

3425

6378

4空閒9

id使用的記憶體頁id

00,112

23釋放掉id=1,記憶體頁id為2的那條記憶體空間資訊:

位址頁id狀態0

0121

342空閒

5637

84空閒9

id使用的記憶體頁id

00,123

現在,就出現了之前的情況:目前一共有4個記憶體空間,但是不連續。

不過,因為現在是分頁管理機制,因此,現在仍然可以繼續申請長度為4的記憶體空間。

沒有碎片,能夠盡量地全部用完空間。但仔細想想,這種優勢背後,也是需要付出大量代價的。

分頁的方式下,程式需要記錄記憶體頁id,每次使用時,需要從記憶體頁id翻譯成實際記憶體位址,多了一次轉換。

而且這種模式,會浪費一些記憶體,比如上面申請3個記憶體空間,實際分配了2個頁面共4個記憶體空間,浪費了1個記憶體空間。

還有乙個要注意的地方,這個時候"段基址+段內偏移位址"經過段部件處理後得到的線性位址就不再是實體地址了,而是虛擬位址了。

從下圖我們能夠清楚的看出來我們最後的線性位址表示的是頁表的位址,而不是實體地址了。

無論cpu在什麼模式下,段內偏移位址又稱為有效位址或者邏輯位址(只是叫法不一樣罷了),例如實模式下mov ax, [0x7c00]0x7c00就是邏輯位址(或有效位址),但這條指令最終操作的實體地址是ds*16+0x7c00

linux最初就是在32位的80386系列上設計的,並且沒有使用分段機制,所以在linux上邏輯位址和線性位址就是一回事了。

一圖以概括:

我的部落格:

記憶體位址分配

inti 1 intj 1 cout i endl j endl 2 函式引數列表的存放方式是,先對最右邊的形參分配位址,後對最左邊的形參分配位址。3 little endian模式的cpu對運算元的存放方式是從低位元組到高位元組的 0x1234的存放方式入下 0x4000 0x34 0x4001 ...

理解記憶體位址

物理記憶體 記憶體條實際提供的記憶體空間 記憶體定址 在記憶體上找到正確的位置以便進行訪問的過程 硬編碼 通過實體地址操作物理記憶體的寫碼方式 線性記憶體和物理記憶體 相似點 從0編號,線性增加 不同 1.實體地址一一對應於實際物理記憶體空間的位置,而線性位址可多對一 多個線性位址對應乙個實體地址 ...

記憶體位址對齊

記憶體位址對齊,是一種在計算機記憶體中排列資料 訪問資料的一種方式,包含了兩種相互獨立又相互關聯的部分 基本資料對齊和結構體資料對齊。當今的計算機在計算機記憶體中讀寫資料時都是按字 word 大小塊來進行操作的 在32位系統中,資料匯流排寬度為32,每次能讀取4位元組,位址匯流排寬度為32,因此最大...