其他分享
首页 > 其他分享> > 段页式访存——逻辑地址到线性地址的转换

段页式访存——逻辑地址到线性地址的转换

作者:互联网

继续底层知识,想要看懂 PWN 题和理解汇编代码,必须要搞懂这些底层知识啊。搞懂 movl 8(%ebp), %eax(IA-32 架构)真的不容易。。。

movl 8(%ebp), %eax(IA-32)

首先我们来看这条指令什么意思:把内存中某个地址的 32 位数据,放入 eax 寄存器中。你可以理解为地址为:%ebp + 8。但是,这只是虚拟地址。而且在 IA-32 架构中,虚拟存储空间是段页式。也就是说,在执行这条命令的时候,为了找到主存的物理地址,要经过段和页两种结构。搞懂这两种东西真的不容易!来吧,让我们开始吧。

存储地址要经过以下阶段:

逻辑地址 -------> 线性地址 -------> 物理地址

(以下内容全是 IA-32 架构)

分段过程

分段过程的实质就是逻辑地址 -------> 线性地址 的过程

整个过程如下图所示:

   

逻辑地址实际是由 48 位组成的,前 16 位包括「段选择符」后 32 位「段内偏移量」

如何通过「段选择符」找到段基址

之前我们说过:逻辑地址一共有 48 位。前 16 位是段选择符。

   

这 16 位的格式如上图。

整体过程就是:

通过索引在描述符表中找到段基址,用图片叙述就是这样(图片左边):

   

其中 GDT 和 LDT 的首地址,存在用户不可见的寄存器中:

   

下面的内容将详细介绍这些你不知道的名词

什么是「描述符表」

实际上就是「段表」,由「段描述符(段表项)」组成。有三种类型:

什么是「段描述符」

段描述符就是表项,一种记录每个段信息的数据结构。我们之前说到的「段选择符」就是描述符表(段表)中的索引。

一图讲清楚段描述符:

   

一个段描述符的大小是 8B。现在把段描述符的每个部分讲清楚:

问一个问题

像 GDT 表这样的表存在哪里?存在主存里面!

好,既然存在主存里面,就有一个速度的问题。这种问题的解决办法就是用 Cache

用 Cache 解决分段问题

学习如何用 Cache 解决分段问题之前。我们得先知道逻辑地址的前 16 位地址怎么来的。

逻辑地址的前 16 位是段选择符,「段选择符」存在寄存器中:

   

每个寄存器的作用如下:

   

也就是每个进程的每个段都有相应段的段选择符寄存器

有了「段选择符」以后,就能拿到对应表中的段基址了。那 Cache 又是怎么派上用场的呢?

   

只有第一次取地址的时候才会去主存中访问 GDT 表。之后根据「段选择符」选择地址的时候,都是在 Cache 里面去找,不用再访问主存

   

(MMU 是 Memory Management Unit 内存管理单元)

一点小变化

为使能移植到绝大多数流行处理器平台,Linux 简化了分段机制

   

为了简化,初始化的时候,所有的基地址都是 0

总结

小小的总结一下:如何从逻辑地址 -------> 线性地址

          



作者:madao756
链接:https://www.jianshu.com/p/fd2611cc808e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:GDT,访存,段页,32,描述符,偏移量,地址,选择符
来源: https://www.cnblogs.com/pipci/p/12403976.html