首页
社区
课程
招聘
[求助]保护模式 向下扩展 求教!
发表于: 2010-10-13 17:31 5940

[求助]保护模式 向下扩展 求教!

2010-10-13 17:31
5940
最近在研究保护模式,一个问题一直在困扰我,就是段的向下扩展,看雪里有一篇关于向下扩展的,但还是没看明白,希望达人能给我解惑
假设我有一个16位段,段基址是 0x2000h,段限是0x5h,那么这个段大小应该是0x6H,但是向下扩展的布局应该是什么样的呢?
第一种可能是:

0                <-------- 低地址

0x1ffbh      <-------- 段限(0x2000h-0x5h得到)
........
0x2000h    <-------- 段基址(不确定这该不该是段基址)

0xffff          <-------- 高地址

那有效的区域应该是那一块?我觉得应该是 0x1ffb~0x2000h,但书上说偏移的有效位应该是Limit+1 ~ 1M-1,那么假设我要访问第一个自己,Limit+1 = 6,我实在是想不通 段基址和6是如何关联起来访问到第一个字节的。(而且我对第一个字节的位置在哪里也不确定,是0x1ffbh还是0x2000h-1?

第二种可能是,只要是向下扩展的,那么段就从 Base+Limit 变成了Limit+1 ~ 0xffffh,也就是如下:
0                <-------- 低地址

0x2000h    <--------
........
0x2005h    <--------
........
........
0xffff          <-------- 高地址

这时段的大小从 6 变成了 0xffff-0x2005h+1,那么这个时候,段基址为0x2000h(我认为),段偏移有效位 Limit+1~1M-1我就能理解了,有效的区域是 0x2005h~0xffff,但感觉这样思考很别扭,而且和书上说的:由此可见,如果一个段是向下扩展的,则所有的偏移必须大于限长,因为其限长是指下限,其基地址从高地址出开始,和蓝色的那句话冲突!
我确实分析不清楚了,网上关于向下扩展的资料极少,哎。
另外,我也看到说ED的方向决定了计算的方式(加/减),但对这句话没有深刻的认识。
请教各位了,万分感谢!!!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 179
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
接上篇,我刚才发现,在第一种布局下,如果0x2000h为基址,0x1ffb~0x2000h为有效区域,那么如果要访问到0x1ffffh那个字节,就是要0x2000h-1,而-1 <==> 0xFFFF(有符号)<==>0xFFFF(无符号)<==>1M-1,而1M-1正好处于书上所说的Limit+1~1M-1的有效偏移去,难道CPU把对向下扩展的段的偏移强制看成是无符号的,然后和基址相加吗??
2010-10-13 17:41
0
雪    币: 179
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
刚才又仔细想了想,书上原文是:
数据段的扩展方向和段界限一起决定了数据段内偏移的有效范围。当段最大为1M字节时,在向高端扩展的段内,从0到Limit的偏移是合法有效的偏移,而从Limit+1到1M-1的偏移是非法无效的偏移;在向低端扩展的段内,情形刚好相反,从0到Limit的偏移是非法无效的偏移,而从Limit+1到1M-1的偏移是合法有效的偏移,注意边界值Limit对应地址的有效性。段最大为4G时,情形类似。由此可见,如果一个段是向下扩展的,则所有的偏移必须大于限长因为其限长是指下限,其基地址从高地址出开始。反之,若一个段是向上扩展的,则所有偏移必须小于等于限长,因为其限长是指上限,基地址从低地址处开始。通过使用段环绕,可以把向下扩展段定义到任何线性地址且可定义为任何大小。
我觉得第一种布局应该是正确的,也就是向下扩展时,段边界应该是BASE-Limit => 0x2000h-5 => 0x1ffbh,仔细看这句:“由此可见,如果一个段是向下扩展的,则所有的偏移必须大于限长,因为其限长是指下限,其基地址从高地址出开始。”,也就是说,对于这个向下扩展的段来说,0x1ffbh确实是下限,任何有效的地址都要大于0x1ffbh,(我很奇怪为什么不是大于等于0x1ffbh)。
但是对于Limit的有效区域是Limit+1~1M-1还是不明白。我自己的猜想是,访问向下扩展的段的时候,是通过 base+负数实现的,比如 base+(-1) => base-1来访问0x1fffh,base-6来访问0x1ffbh,(再一次奇怪为什么0x1ffbh不是有效的地址),然后把负的索引看成无符号数来判断是否在Limit+1~1M-1之间,也就是说,判断一次对向下扩展的段是否有效的步骤是:
1。首先假设有一个负的索引 X,那么即将访问的地址是:BASE+X,注意X是负数,条件1是BASE+X>BASE-Limit(再再一次奇怪为什么0x1ffbh不是有效的地址)。
2. 将负数X看成一个无符号整数,然后条件2:(DWORD)X > Limit && (DWORD)X <= 1M-1
如果1和2两个条件都满足,那么本次访问是成功的。

以上仅为猜想,望各位积极讨论-_-

另外:对书中“通过使用段环绕,可以把向下扩展段定义到任何线性地址且可定义为任何大小。”一句不明白,哪位大侠可以解释?
2010-10-13 18:47
0
雪    币: 179
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
刚刚看了下Intel的白皮书,在书中有这么一段话:

For expand-down data segments, the segment limit has the same function but is interpreted differently. Here, the effective limit specifies the last address that is not allowed to be accessed within the segment; the range of valid offset is from (Effective-limit + 1) to FFFFFFFFH if the B is set and from (effective-limit + 1) to FFFFH is the B is clear; An expand-down segment has maximum size when the segment limit is 0.

这应该是最权威的解释了,还是以2000h为例,5的limit,16位段,那么内存布局应该如下:

0                <-------- 低地址

0x2000h    <--------
........
0x2005h    <--------  Effective-Limit => Base+Limit
........
........
0xffff          <-------- 高地址

那么这个段的有效地址范围应该为 0x2006h~0xffffh,也即Limit的有效范围是从Limit+1~1M-1,当然,所生成的线性地址应该在2006h到1m-1的范围内。

对于这个问题,我只有一个疑惑了,为什么要从Limit+1开始,这说明这个区域的可访问内存因该是从:0x2006h~0xffffH,0x2005那个位置为什么不允许访问??

谢谢
2010-10-13 20:33
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
向下扩展的是和堆栈段类似的,intel硬件设计不会有错的,你自己好好理解一下。
2010-10-14 09:06
0
游客
登录 | 注册 方可回帖
返回
//