關於邏輯地址、線性地址、虛擬地址、物理地址的理解


最近在看《深入理解Linux內核》,在第二章《內存尋址》中提到了邏輯地址、線性地址、虛擬地址、物理地址的概念。

原文是這么描述的:

邏輯地址(logical address):
包含在機器語言指令中用來指定一個操作數或一條指令的地址。這種尋址方式在80x86著名的分段結構中表現得尤為具體,它促使MS-DOS或Windows程序員把程序分成若干段。每一個邏輯地址都由一個段(segmemt)和偏移量(offset或displacememt)組成,偏移量指明了從段開始的地方到實際地址之間的距離。
	
線性地址(linear address)(也稱虛擬地址 virtual address):
是一個32為無符號整數,可以用來表示高達4GB的地址,也就是,高大4 294 967 296個內存單元。線性地址通常用十六進制數字表示,值的范圍從0x00000000到0xffffffff。
	
物理地址(physical address):
用於內存芯片級內存單元尋址。它們與從微處理器的地址引腳發送到內存總線上的電信號相對應。物理地址由32位或36位無符號整數表示。

在文中,把線性地址和虛擬地址等同,並詳細定義了邏輯地址。但是,把邏輯地址的定義套入到我們平時交流中提到的邏輯地址定義,怎么這么別扭呢?

在工作中,我們經常把邏輯地址等同於虛擬地址,基本不用線性地址,例如對於以下C程序:

#include <stdio.h>
#include <stdlie.h>

int main(int argc, char **argv)
{
	int var = 1;
	char *mvar = malloc(10);
	printf("var address: %p\n", &var);
	printf("mvar address: %p\n", &mvar);
}

執行的結果

[GMPY@17:04 tmp]$./test 
var address: 0x7ffe9ddceb9c
mvar address: 0x7ffe9ddceba0

我們在工作中交流時,經常把上面打印出來的地址叫做虛擬地址,有時候也會叫做邏輯地址,而非書中這么復雜這么繞人的概念。

那么,我們究竟怎么區分這幾個地址?


關於邏輯地址的理解

在《深入理解Linux內核》中描述了 在80x86處理器中 地址的轉換:

邏輯地址 -> [分段單元] ->線性地址 -> [分頁單元] -> 物理地址

其中 分段單元分頁單元 是硬件電路,分別用於 從邏輯地址到虛擬地址從虛擬地址到物理地址的轉換。注意的是,作者特意強調了 在80x86處理器中

在書中 Linux中的分段 小章節得出一個非常重要的結論:

這可以得出另一個重要結論,在Linux下邏輯地址與線性地址是一致的,即...

在Linux下邏輯地址與線性地址是一致的!!

既然是一致的,為什么還要區分邏輯地址和線性地址?歷史已經不可究,但不妨礙我 瞎想 遐想:

Intel體系下的工程師提出分段的特點時,為了區別分段與分頁前的地址,苦思冥想后造出了邏輯地址的概念

為什么要強調是Intel體系呢?因為 以intel為代表的有限的一些體系規定了要用分段+分頁(arm體系貌似只有分頁)。實際上 與分段相比,Linux更喜歡使用分頁方式,換句話說,Linux不喜歡用分段,但是為了兼容,只能走走形式,意思意思一下,在實現中讓邏輯地址虛擬地址

結論

如果非要定義邏輯地址,我們可以把邏輯地址簡單理解為

為了區分分段與分頁的地址,把分段前的地址叫做邏輯地址,把分頁前的地址叫做虛擬地址

在Linux中,我們可以認為 邏輯地址=虛擬地址=線性地址,因此只剩下兩類地址:

虛擬地址:cpu訪問的地址,即C語言中"%p"打印出來的地址
物理地址:物理內存實際地址,經過MMU從虛擬地址轉換而來

上述僅僅是個人理解,如果有不對的地方,希望一起交流


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM