認識各種內存地址_網頁設計公司

※想知道最厲害的網頁設計公司嚨底家"!

RWD(響應式網頁設計)是透過瀏覽器的解析度來判斷要給使用者看到的樣貌

什麼是物理地址?

物理地址就是內存單元的絕對地址,物理地址0x0000就表示內存條的第一個存儲單元,0x0010(16進制)就表示內存條的第17個存儲單元,一個存儲單元是1byte(8bit)。

你問為什麼是1byte?

一個內存條是由若干個黑色的內存顆粒構成的。每一個內存顆粒叫做一個chip。

每個chip中又疊了若干bank

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

什麼是線性地址和虛擬地址?

在80286系列以前,CPU只支持實模式操作模式。16位寄存器想要對20位地址線進行尋址,使用分段機制,段基址(16位) x 16(左移4位) + 段內偏移地址(4位)就是物理地址了。
這樣的好處是所見即所得,程序員指定的地址就是物理地址,物理地址對程序員是可見的。同時也帶來了一些問題:
1) 無法支持多任務。
2) 程序的安全性無法得到保證。
(根本原因就是一個程序直接修改了其他程序的內存,導致崩潰)

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

80286系列之後就進入32位CPU時代了,32位寄存器可以直接訪問32位地址總線。但是在保護模式下,地址仍然採用“段地址:偏移地址”的方式來表示。
段值仍然由原來的16位的cs、ds等寄存器表示,但是此時它們僅僅是一個索引,這些個索引指向一個數據結構的表項,表項中詳細定義了一個段的起始地址、界限、屬性等內容,這個數據結構,叫做GDT(其實還可能是LDT),GDT中的每一個表項,叫做描述符。
這裏我們就詳細看一下保護模式的尋址方式吧。

1) 尋址時,先找到gdtr寄存器,從中得到GDT的基址。
2) 有了GDT的基址,又有段寄存器中保存的索引,可以得到段寄存器“所指”的那個表項,即所指的那個描述符。
3) 得到了描述符,就可以從描述符中得到該描述符所描述的那個段的起始地址。
4) 有了段的起始地址,將偏移地址拿過來與之相加,便能得到最後的線性地址。
5) 有了線性地址,經過變換,即可得到相應的物理地址。

保護模式雖然解決了內存不被跨界訪問,但是其也帶來了新的問題,那就是內存碎片。
首先我們了解一下內存碎片為何產生:
首先假設我們有10B內存:

ID 首地址 尾地址 長度 狀態
0 0 9 10 空閑

當程序申請一個長度為3的內存空間后:

ID 首地址 尾地址 長度 狀態
0 0 2 3
1 3 9 7 空閑

當程序再申請一個長度為2,以及長度為4的內存空間后:

ID 首地址 尾地址 長度 狀態
0 0 2 3
1 3 4 2
2 5 8 4
3 9 9 1 空閑

此時,只剩1個可用空間。如果這時程序再來申請長度大於1的空間,就申請不了,也就是內存不夠。
現在,釋放掉ID=1的空間:

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

透過資料庫的網站架設建置,建立公司的形象或購物系統,並提供最人性化的使用介面,讓使用者能即時接收到相關的資訊

ID 首地址 尾地址 長度 狀態
0 0 2 3
1 3 4 2 空閑
2 5 8 4
3 9 9 1 空閑

我們發現,現在可用內存空間為3,但是,這3個空閑空間,並不是連續的。
所以,如果程序現在申請長度為3的內存空間,同樣會申請不了,會出現內存不夠。我們把這種情況,稱之為內存碎片

那內存碎片怎麼解決呢?於是就有了分頁機制,接下來我們詳細講一下分頁:
首先,把物理內存,按照某種尺寸,進行平均分割。比如我現在以2個內存單位,來分割內存,也就是每兩個連續的內存空間,組成一個內存頁:

地址 頁ID 狀態
0 0 空閑
1
2 1 空閑
3
4 2 空閑
5
6 3 空閑
7
8 4 空閑
9

接着,系統同樣需要維護一個內存信息表:

ID 使用的內存頁ID

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

地址 頁ID 狀態
0 0
1
2 1
3
4 2 空閑
5
6 3 空閑
7
8 4 空閑
9
ID 使用的內存頁ID
0 0,1

接着,程序再申請長度為1,長度為2的空間:

地址 頁ID 狀態
0 0
1
2 1
3
4 2
5
6 3
7
8 4 空閑
9
ID 使用的內存頁ID
0 0,1
1 2
2 3

釋放掉ID=1,內存頁ID為2的那條內存空間信息:

地址 頁ID 狀態
0 0
1
2 1
3
4 2 空閑
5
6 3
7
8 4 空閑
9
ID 使用的內存頁ID
0 0,1
2 3

現在,就出現了之前的情況:目前一共有4個內存空間,但是不連續。
不過,因為現在是分頁管理機制,因此,現在仍然可以繼續申請長度為4的內存空間。
沒有碎片,能夠盡量地全部用完空間。但仔細想想,這種優勢背後,也是需要付出大量代價的。
分頁的方式下,程序需要記錄內存頁ID,每次使用時,需要從內存頁ID翻譯成實際內存地址,多了一次轉換。
而且這種模式,會浪費一些內存,比如上面申請3個內存空間,實際分配了2個頁面共4個內存空間,浪費了1個內存空間。

還有一個要注意的地方,這個時候”段基址+段內偏移地址”經過段部件處理后得到的線性地址就不再是物理地址了,而是虛擬地址了。
從下圖我們能夠清楚的看出來我們最後的線性地址表示的是頁表的地址,而不是物理地址了。

什麼是邏輯地址和有效地址?

無論CPU在什麼模式下,段內偏移地址又稱為有效地址或者邏輯地址(只是叫法不一樣罷了),例如實模式下mov ax, [0x7c00]0x7c00就是邏輯地址(或有效地址),但這條指令最終操作的物理地址是DS*16+0x7c00
Linux最初就是在32位的80386系列上設計的,並且沒有使用分段機制,所以在Linux上邏輯地址和線性地址就是一回事了。

總結

一圖以概括:

我的博客:https://geanqin.github.io/

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

當全世界的人們隨著網路時代而改變向上時您還停留在『網站美醜不重要』的舊有思維嗎?機會是留給努力改變現況的人們,別再浪費一分一秒可以接觸商機的寶貴時間!

您可能也會喜歡…