码迷,mamicode.com
首页 > 系统相关 > 详细

Linux内存寻址

时间:2015-12-15 21:14:17      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:

我会尽力以最简洁清晰的思路来写这篇文章。

 

所谓内存寻址也就是从写在指令里的地址,转化为实际物理地址的过程。因为操作系统要兼顾许多东西,所以也就变得复杂。

 

逻辑地址 → 线性地址 → 物理地址

 

逻辑地址 = 段 + 偏移量

 

因为:最开始cpu中的alu宽度只有16位,但地址总线宽度有20位。所以设置四个段寄存器:cs(指令),ds(数据),ss(堆栈),es(其它)。

每个段寄存器16位,对应地址总线高16位。每条指令中的16位内部地址与某个段寄存器中内容相加,得到20位的实际地址。

 

上述的16位内部地址到20位实际地址的转换还是8086的时代。

到了80386,32位cpu的时代,许多情况都发生改变。其中一点:要实施“保护模式”。还要兼容过去的段寄存器。

 

于是,之前的公式从新写为:

             逻辑地址 = 段选择符(16位) + 偏移量(32位)

 

所以对80386cpu的寻址还是要基于从前8086寻址方式来理解,《linux内核源代码情景分析》中这样描述:

技术分享

 

可简单记为:段寄存器(段选择符) → 地址段描述结构(段描述符) → 基地址 → 指令中发出的地址 + 基地址 = 物理地址

 

地址段描述结构(段描述符) 从何而来:在cpu中增设两个寄存器,一个是全局性的段描述表寄存器GDTR;一个是局部性的段描述表寄存器LDTR。

                      段描述符地址  =  段选择符index字段×8 + gdtr/ldtr寄存器中的值

 

这张图可以表现,怎样由段寄存器(段选择符)得到段描述符 。

技术分享

 

段选择符得到“段”的过程,一种是访问段描述表得到段描述符。

另外还可以通过非编程寄存器,不访问段描述表得到段描述符。

总之,是段选择符(段寄存器) → ( 段描述符表 → )段描述符 → 基地址的过程。

技术分享

 

段描述符:

技术分享

 

 

继续推导之前的式子:

            段描述符的获得:段选择符index字段×8 + gdtr/ldtr寄存器中的值

            基址 = 段描述符Base字段

            逻辑地址 = 段选择符(16位) + 偏移量(32位) = 段描述符Base字段 + 偏移量

技术分享

参考资料:

   《汇编语言》王爽

   《linux内核源代码情景分析》毛德操

   《Understanding the Linux Kernel》Daniel P. Bovet / Marco Cesati 

Linux内存寻址

标签:

原文地址:http://www.cnblogs.com/rixiang/p/5049312.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!