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

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

原文是這麼描述的:bash

邏輯地址(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位無符號整數表示。

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

在工做中,咱們常常把邏輯地址等同於虛擬地址,基本不用線性地址,例如對於如下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);
}

執行的結果io

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

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

那麼,咱們究竟怎麼區分這幾個地址?test


關於邏輯地址的理解

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

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

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

在書中 Linux中的分段 小章節得出一個很是重要的結論:gc

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

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

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

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

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

結論

若是非要定義邏輯地址,咱們能夠把邏輯地址簡單理解爲

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

在Linux中,咱們能夠認爲 邏輯地址=虛擬地址=線性地址,所以只剩下兩類地址:

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

上述僅僅是我的理解,若是有不對的地方,但願一塊兒交流

相關文章
相關標籤/搜索