当使用80x86微处理器时,我们必须区分三种地址:
1.逻辑地址(logical address)
包含在机器语言指令中用来指定一个操作数或者一条指令的地址。由一个段(segment)和偏移量(offset)组成。
2.线性地址(linear addres,也称虚拟地址 virtual address)
是一个32位无符号整型。是我们编程时接触到的都是这种。
3.物理地址(physical address)
用于内存芯片级内存单位元寻址。
内存控制单元(MMU)通过一种称为分段单元(segmentation
unit)的硬件电路把一个逻辑地址转换成线性地址;接着,第二个成为分页单元(paging unit)的硬件电路把线性地址转换成一个物理地址。
Linux 中的分段
与分段相比,linux更喜欢使用分页方式。运行在用户态的所有linux进程都使用一对相同的段来对指令和数据寻址。这两个段就是所谓的用户代码段和用户数据段。类似地,内核态的分别为内核代码段和内核数据段。
与段相关的线性地址从0开始,达到231-1的寻址限长。
所有的段都从0x0开始,那就是在linux下逻辑地址与线性地址是一致的。即逻辑地址的偏移量和线性地址相等。
硬件中的分页
为了效率起见,线性地址被分成以固定长度为单位的组,成为页(page)。页内部连续的线性地址被映射为连续的物理地址。
从80386开始,Intel处理器的分页单元出来4KB的页。
32位的线性地址被分成3个域:
Directory (目录),最高10位
Table (页表),中间10位
Offset (偏移量),最低12位
线性地址的转换分两步完成,每一步都基于一种转换表,第一中转换表称为目录表(page
directory),第二中转换表称为页表(page table)。