linux X86下的段地址_段内偏移_虚拟地址_线性地址_物理地址

本文描述的是基于Linux下的x86的段地址、段内偏移、虚拟地址、线性地址、物理地址的转换与关系。

我们先来看一个二进制可执行程序test

linux X86下的段地址_段内偏移_虚拟地址_线性地址_物理地址

linux X86下的段地址_段内偏移_虚拟地址_线性地址_物理地址

 

段基地址:

test加载运行时,linux使用预先设置好的GDTRLDTR寄存器,找到对应的段描述符表,已经表项。然后,从断描述符表项(entry)中拿到段基地址。在linux实现中,所有段的基地址都是0,最大偏移为4GB(32bits机器)

 

段内偏移地址:

在上面test汇编代码截图中,黄色的框表示偏移地址,当test被加载运行时,这个地址就是段式寻址中的段内偏移地址。

 

下面,我们来描述程序从加载到运行的过程:

Linux加载二进制test到内存后,构建mmu的页表项。

将段基地址+段内偏移地址构成的虚拟地址直接用作页寻址的线性地址。然后将线性地址和test被加载到的物理内存的物理地址做页式映射,即线性地址0 映射 到test的加载地址。

同时设置pc指针的值为test文件中的entry指示的地址(entry指示test文件中入口指令地址偏移)

设置好后,cpu就能找到test的第一条指令并加载了:

cpu找第一条指令的地址转换过程:

段基地址0+段内偏移(entry指示的偏移地址<pc指针>)  构成了寻址的线性地址,这个线性地址被mmu映射到了test加载地址处开始的偏移entry指示的地址偏移处。

linux X86下的段地址_段内偏移_虚拟地址_线性地址_物理地址

linux X86下的段地址_段内偏移_虚拟地址_线性地址_物理地址

linux X86下的段地址_段内偏移_虚拟地址_线性地址_物理地址