免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 68705 | 回复: 18

[内存管理] 关于内存管理的一个小问题 [复制链接]

论坛徽章:
6
2015年迎新春徽章
日期:2015-03-04 10:16:53操作系统版块每日发帖之星
日期:2015-08-04 06:20:002015亚冠之鹿岛鹿角
日期:2015-08-05 16:51:182015亚冠之全北现代
日期:2015-08-07 17:14:392015亚冠之武里南联
日期:2015-08-11 15:33:03数据库技术版块每日发帖之星
日期:2016-02-02 06:20:00
发表于 2017-05-03 16:45 |显示全部楼层
一直在看内存管理的分段机制,向各位大侠求教一下

我们知道逻辑地址包括16位的段选择符加上32位的偏移量

段描述符中包含32位段基址和20位段限长以及若干位段属性

逻辑地址向线性地址转换时首先通过段选择符找到段描述符

然后段描述符中的32位基地址加上32位偏移量就得到了线性地址

那么问题来了,
1.段限长都是20位那么段偏移量是32位有什么意义?为啥偏移量不是20位
2.虚拟地址空间是2的14次方乘以4G即64T,而线性地址空间是4G,这个转换的过程到底是什么样的?,始终没想明白,求解答

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
发表于 2017-05-03 19:58 |显示全部楼层
既然楼主发问了,我就来解释一下其中的原因。

  要了解这个问题,首先我们需要知道 4 种地址,即虚拟地址,逻辑地址,线性地址和物理地址。每种地址的理解如下:
  1. 虚拟地址
      每个进程运行时,只看得到自己在整个内存中运行,它会认为整个内存都是它的,此时,从进程的角度来看,内存提供的地址叫做虚拟地址。
      虚拟地址也就是进程直接接触的内存地址。
  2. 逻辑地址
      为了让进程觉得只有它一个进程在使用整个内存,而不被其他进程干扰,内核使用了分段机制,将内存分做一段一段的,每个段里面包含了代码段,数据段
      和其他各种段,内核使用段机制隔离了进程直接的内存访问。此时,内核使用逻辑地址来寻址每个段。逻辑地址有一个段选择符合一个偏移值构成。
      段选择符是由 20 位的段寄存器构成,偏移值由 32 位值构成。
      逻辑地址在寻址时,先通过段选择符在 GDT 或 LDT 中获得段描述符,段描述符有 8 字节构成,段选择符从 GDT 或 LDT 中获得段描述符之后,
      段描述符中函数该段在线性地址空间中的基地址,基地址由 32 位长。获得基地址之后,在和偏移值相加,就能获得线性地址。
      所以逻辑地址是相对分段机制而言。
  3. 线性地址
      线性地址也就是内核虚拟内存层次的地址,32 位系统中,虚拟内存将内存看做一个连续长度的地址空间,其长度为 2 的 32 次方,也就是 4G。
      线性地址主要负责分页机制下将虚拟内存对应到物理内存。
  4. 物理地址
      物理地址,顾名思义就是硬件内存的地址,该地址表示硬件内存存储器上的地址。

通过上面的前提,
  对于问题一:
       段限长的粒度是由段描述符中的 G 标志位控制,该位置位时表示段的限长为 4Kb~4G, G位清零,段限长为 1B ~ 1M。
       逻辑地址空间最多包含 16K 个段,而每个段长最长可以是 4G, 是的虚拟地址空间最大长度为 64T。
       段限长是 20 位,那么也就是按 G 值位的情况算,每个段长为 4G, 所有需要使用 32 位偏移来寻址 4G 里面的内容。

     问题 2
      虚拟地址是在逻辑地址之上,也就是每个进程都有一个虚拟地址,该虚拟地址长为 4G,进程是运行在分段机制之上
      由于分段机制的存在,它会让进程感觉整个 4G 的虚拟地址空间都由它独享。段机制会将进程才分成一个个数据段,代码段等。
      也就是说虚拟地址最终会转换为逻辑地址。
      虚拟地址的转换可以理解为如下:
     1. 虚拟地址正在由一个进程在使用,该进程任务虚拟空间由它独享。该进程的 TSS 里面存储了各种段寄存器的信息。
     2. 每个进程都会有各自的代码段,数据段等,例如这些段的地址会表示为 0x8004800 开始的 4K 是代码段, 0x8004900 开始的 4K 是数据段。
     3. 虚拟地址转换为逻辑地址是会先读取该进程对应的段寄存器,譬如 CS,GS,FS,SS 等,该寄存器里存放段选择符。比如 CS 的值位 0x8,那么他就以该值位索引,
         在 GDT 或 LDT 中查找段描述符,如 GDT[CS] -> 段描述符,获得段描述符之后,从段描述符中获得线性地址的基地址。
     4. 获得基地址之后,使用基地址加上偏移值,就可以获得对应的线性地址。

综上所述,可知
   

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
发表于 2017-05-03 22:13 |显示全部楼层
回复 1# lxy572535121

1. 你是出于什么考虑,要求指定限长的位数必须与指定偏移的位数相等?假设系统就是限制段的长度最大1M,你写的应用程序如果需要大量内存,一个段满足不了你,那多分配几个就是了,虽然你可能觉得不爽,但并没有什么不行的呀,更何况段描述符里有个G标志,也可以表达大的长度;
2. 虚拟地址范围还有这样算的呀?32位系统,指针变量32位,你如何表达64T的地址?就算按照你的思路,你说的这些段也是重叠的,不能用乘法。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
发表于 2017-05-03 22:47 |显示全部楼层
回复 3# _nosay

作者这样提问没有任何问题,
他是对逻辑地址产生疑问,而且 32bit 的系统虚拟地址表示 64 T 没有问题, 32bit 系统线性地址必须是 4G, 物理地址可以大于 4G。

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
发表于 2017-05-04 00:41 |显示全部楼层
回复 4# Buddy_Zhang1

1. 虚拟地址、逻辑地址、线性地址、物理地址,不能硬生生说成4种地址,拿80386来说,A1->段式映射->A2->页式映射->A3,你如何拿这4种地址与A1、A2、A3对应上?2. 你对分段机制要解决的问题,理解是错误的。让每个进程觉得自己独占内存,那是保护模式要解决的事,如果靠分段就解决进程间相互干扰,实模式下用分段为什么还是会相互干扰?
    段寄存器最初出现在8086上,解决ALU16位,地址总线20位的问题,而80386仍然保留段寄存器,是为了兼容性。
3. 段式管理的"段"和代码"段"/数据"段",根本就是没有关系的两样东西,每个段里包含了代码段、数据段和其它各种段,怎么讲?
4. 虚拟地址最多包含16K个段,又是怎么讲?
    是因为保护模式下段寄存器高13位为段描述符索引吗?那也是8K个呀。即使不知道你从哪算的16K,你拿它跟4G相乘,就表示你期望每个段都能表示4G范围,那肯定都重叠在0-4G呀,32位变量,怎么能表示出64T?
5. 在32位系统,你能写个程序,反汇编可以看见,或者可以打印一个动态分配超过4G的地址吗?
6. 20的寄存器,是笔误吗?
7. 线性地址负责通过页式映射将虚拟地址转换成物理地址,你知道自己在说什么吗?
8. sorry

论坛徽章:
6
2015年迎新春徽章
日期:2015-03-04 10:16:53操作系统版块每日发帖之星
日期:2015-08-04 06:20:002015亚冠之鹿岛鹿角
日期:2015-08-05 16:51:182015亚冠之全北现代
日期:2015-08-07 17:14:392015亚冠之武里南联
日期:2015-08-11 15:33:03数据库技术版块每日发帖之星
日期:2016-02-02 06:20:00
发表于 2017-05-04 09:20 |显示全部楼层
回复 3# _nosay
对于问题1我当时是这样想的:既然段限长是1M,那么我们可以把32位段基址的低20位置为零,然后偏移量只要用20位就刚好可以使地址在段限长的1M内变化,这样就不用浪费多余的位(当时没考虑到G标志)
然后现在又有这样的问题:1.段基址有32位,偏移量有32位,都可以寻址4G,用两个不是浪费么?只要一个32位的偏移量就可以寻址4G了
2.两个分段不会重合么?例如一个段基址加上对应的偏移量不会跑到另一个段的范围内么?

论坛徽章:
2
2016猴年福章徽章
日期:2016-02-18 15:30:3415-16赛季CBA联赛之广夏
日期:2016-12-07 08:32:11
发表于 2017-05-04 09:47 |显示全部楼层
本帖最后由 剑魂箫心 于 2017-05-05 19:44 编辑

回复 4# Buddy_Zhang1

论坛徽章:
6
2015年辞旧岁徽章
日期:2015-03-05 16:13:092015年迎新春徽章
日期:2015-03-05 16:13:092015小元宵徽章
日期:2015-03-06 15:58:1815-16赛季CBA联赛之浙江
日期:2016-11-05 14:38:4115-16赛季CBA联赛之新疆
日期:2016-11-11 18:38:06
发表于 2017-05-04 10:05 |显示全部楼层
段限20位,但单位是可调的。还有一个粒度位,设置为1后,段限是以4K为单位的。4K本身有12位,合起来实际段限为32位。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
发表于 2017-05-04 10:18 |显示全部楼层
回复 7# 剑魂箫心

32 位系统的物理地址使用 PAE 可达 64 G, 但线性空间必须是 4G, 虚拟地址和线性地址不是同一个概念!

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
发表于 2017-05-04 10:49 来自手机 |显示全部楼层
本帖最后由 _nosay 于 2017-05-04 10:51 编辑

6# lxy572535121

[size=43.1692px]   这样考虑,偏移位数与限长位数相等就够了。    8086为了方便用16位的偏移得到20位的地址,想到了分段的方法,所以把内存分成一段一段的不是最终目的,而是为了另外一个目的,当时也并没有考虑从一个段跨到另一个段的问题,因为段寄存器的16位值,和偏移里的16位值,全都用于计算目的地址,连个表示长度的地方都没有;
    80386还是纯粹为了寻址的话,就如你说的,用一个32位值就行了,连段寄存器都不需要了,但它要考虑兼容老cpu上的程序,还要支持保护模式。所以除了需要一个32位值表示基址,还需要20位值+G表示长度,以及其它位表示别的属性,这正是段描述符结构设计的依据,以及80386保护模式下改变段寄存器含义的原因。
    另外,保护模式可以基于段式管理设计,也可以基于页式管理设计,段式管理并不是保证每个进程有独立空间必不可少的东西。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP