关于逻辑地址、线性地址、虚拟地址、物理地址的理解

最近在看《深刻理解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从虚拟地址转换而来

上述仅仅是我的理解,若是有不对的地方,但愿一块儿交流

相关文章
相关标签/搜索