1、物理地址:就是物理内存真正的地址,相当于内存中的每个存储单元的门牌号,具有唯一性。CPU最终都要以物理地址去访问内存,只有物理地址才是内存访问的终点站。
在实模式下,{段基址+段内偏移地址}经过段部件的处理,直接输出的就是物理地址,CPU可以直接用此地址访问内存。
2、线性地址:
在保护模式下:{段基址+段内偏移地址} 称为线性地址,不过此时段基址已经不是真正的地址,而是一个称为选择子。它本质是个索引,类似于数组下标,通过这个索引便能在GDT中找到相应的段描述符,在该描述符中记录了该段的起始、大小等信息,这样便得到了段基址。当没有开启地址分页功能时,此线性地址就被当作物理地址来用,可直接访问内存;若开启了分页功能,此线性地址就是虚拟地址(虚拟地址、线性地址在分页机制下是一个概念)。
3、虚拟地址:它要经过CPU 页部件转换成具体的物理地址,这样CPU才能去地址总线上访问内存。
4、逻辑地址:无论在实模式还是保护模式下,段内偏移地址都称为有效地址,也称为逻辑地址,这是程序员可以见到的地址。
这是因为最终的地址是由段基址+段内偏移地址组合而成的,由于段基址已经有默认值了,要么在实模式下的默认段寄存器中,要么就是在保护模式下的默认段选择子寄存器指向的段描述符中,所以只要给出段内偏移地址就行了。
总结:
线性地址、虚拟地址都不是真实的内存地址,他们都是用来描述程序或任务的地址空间。由于分页功能是需要在保护模式下开启的,32位系统保护模式下的寻址空间是4GB,所以虚拟地址或者线性地址就是0~4GB的范围。
转换过程如下:
总结:X86两种模式下地址到底是怎么回事?
线性地址给CPU看的 。CPU不需要知道有多少外设,什么种类的外设,反正它都是用地址来访问,线性地址能让CPU把任何设备当成内存。
逻辑地址是给程序的,不需要知道硬件是怎么设计的。
物理地址是给实际的硬件看的。
逻辑地址要经过操作系统转换成线性地址给CPU,CPU发出线性地址给MMU再将线性地址进行转换得到物理地址去访问设备。
当CPU在实模式下时,物理地址 = 段寄存器:偏移地址
当CPU在保护模式下时,必分段,在由实模式转到保护模式前,必须设置段描述符表和GDT,段描述符存在段描述符表中,此时GDTR使用的是肯定是物理地址【实模式下都是段:偏移形成物理地址,GDTR中32位基址可以直接存储实模式下任何地址】;然后在开启CR0寄存器标志位则进入保护模式;因为保护模式要用到段描述符表GDT,用GDTR找到它,最终才能找到段基址。
进入保护模式后:【开启分页后需要再重新更新GDT,此时GDTR使用的是线性地址】
1、未开启分页时,在保护模式下的 线性地址= 段描述符表中的基址【段选择子】 + 偏移【逻辑地址】= 物理地址;
2、开启分页时,在保护模式下的 线性地址= 段描述符中的基址【段选择子】 + 偏移【逻辑地址】,由于大部分段描述符中的基地址为0,所以此时的线性地址=程序的逻辑地址,这时候CPU需要将线性地址经过CPU内部MMU转换为物理地址才能访问内存;
CR3存储页目录地址【物理地址】,如果存储的是线性地址的话,这样的话就会递归,因为线性地址转物理地址必须要用到CR3才能找到页目录首地址。
现代系统中GDT表中基地址都设置为0,那么这样就是平坦模式!这样的话逻辑地址就等于线性地址了!!
————————————————
版权声明:本文为CSDN博主「jadeshu」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jadeshu/article/details/100187374