Chinaunix首页 | 论坛 | 博客
  • 博客访问: 346888
  • 博文数量: 108
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 65
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-16 11:38
文章分类
文章存档

2016年(2)

2015年(44)

2014年(62)

分类: LINUX

2014-04-18 22:56:35

如果你学习计算机组成原理的话,关于x86实模式介绍 中就有这样的描述:

x86体系的处理器刚开始时只有20根地址线,寻址寄存器是16位。我们知道16位的寄存器可以访问64K的地址空间,如果程序要想访问大于64K的内存,就需要把内存分段,每段64K,用段地址+偏移量的方式来访问,这样使20根地址线全用上,最大的寻址空间就可以到1M字节,这在当时已经是非常大的内存空间了。 物理地址=左移4位的段地址+偏移地址。

可是当你仔细想一下你就会发现,这是为什么呢?其中的原理他还是没有说清楚,我就是郁闷了快半个学期了,后来找了老师问了一下,才算真的明白了

教科书上只讲:16+4=20位,所以16位段地址左移4位+16位偏移=20位物理地址。很多人也只是死记,其实并不知道其含义,而且还会感到晕,怎么16位左移4位,再加16位偏移就成20位了?


这下面是我在google上搜索的一个博客,挺有意思的,如下:

最近实在颓废,居然捡起一本汇编来看

人生实在是杯具

就在刚才,忽然发现自己对实模式的理解,有些错误(也许现在的理解才是错的)

问么个,么个说他忘光了,我一下就杯具了

8086 的 CPU 寄存器有 16位宽,也就是说它能取到的最大值为 FFFF H

如果一切都是如此美好,8086的CPU能够控制的地址也是16位的,从0000~到FFFF H

可是事实总是不近人情,8086的地址总线是20位宽的,也就是说它一次能通过的最大数据是 FFFFF H(比16位多了一个F)

为了充分的利用那20位的位宽,intel的工程师,设计了一种间接的寻址方式

实际地址=段寄存器内容×10H+偏移量寄存器内容

有趣的事发生了

寄存器能取到的最大值是 FFFF H,

我们把FFFF H带入到上面的公式,算一算

FFFF H  * 10 H + FFFF  > FFFFF H

所得到的结果,超过了20位

so

我在想,我们是不是搞反了一个问题,限制内存访问的是20位宽的数据总线,而不是实模式下的内存访问方式

即 实际地址=段寄存器内容×16+偏移量寄存器内容 -> 这种方式能够访问超过20位的地址空间(很真确,但是这个并不是重点


但是,数据总线只有20位的宽

类似段寄存器内容为 FFFF ,偏移寄存器为 FFFF 的情况是不可能出现的?

但愿我没有错.. ...(怎么不会出现,也会出现,下面我就介绍一下为什么

 

其实,道理也简单,如果基址寄存器(16位),偏移量寄存器(16位)都用上的话(不过确实也都用上了),

基址            1111 1110 1010 0011 1001

4

  1110 1010 0011 1001 0000

    +

偏移量:             1001 1110 1100 0101 1010

        ===================================

                             1000 1000 1111 1110 1010

即物理地址为:0x88fea=561130 相当于大约是56k的地址了,但是这个56k(一个段中)的固定的物理地址也可以由另外的基址和偏移量构成,你想一想也就清楚了,是不是呀。

 

也就是说,一个基址和偏移量对应的是一个固定的物理地址,但是一个物理地址可以对应多个基址和偏移量了,

 

所以说程序员在访问一个实际地址的时候可以用不同的数据,

有一个问题就是程序用是以段来管理的,此时,如果你知道了一个段的基址和偏移量,此时如果你想知道下一个段得地址的话,程序员就得自己算了,因为段的值是不连续的,呵呵,

 

总算解释完了,应该明白了吧,呵呵(这个时候你该知道了,为啥一个段容量是64k了吧,其实就是偏移量寄存器的最大值,而你任意给出一个值,就会对应着一个段中的唯一地址,可能你给的两个值会指向同一个物理地址呢。。。。)

 

 

阅读(1868) | 评论(0) | 转发(0) |
0

上一篇:分段与分页机制小结

下一篇:boa 0.94.13

给主人留下些什么吧!~~