三、物理地址和段的概念

来源:互联网 发布:linux中man的用法 编辑:程序博客网 时间:2024/06/09 19:42

1.   物理地址的概念:

       a. 物理地址就是指CPU的内存地址空间中的地址;

       b. 内存地址空间将所有不同存储设备的存储空间都整合成了一个以为线性的地址空间;

       c. 其中每个内存单元都对应了一个地址,所有内存单元按照地址从低到高线性排列(这里定义一个内存单元的宽度是1B);

       d. 每个存储设备都占据内存地址空间中不同的部分;


2.   16位CPU的定义:

       a. 三大必要条件:

          (1)ALU是16位的;

          (2)寄存器最宽为16位的;

          (3)寄存器和运算器之间的通路是16位的;

       b. 这也意味着CPU所处理的一切数据(当然包括地址数据)统统都是16位的;

       c. 同样,n位CPU的定义也是按照上面的形式给出;


3.   由CPU和内存之间的效率差异引出“段”的概念:

       a. 由于CPU太快,效率太高,而内存相对来说太慢,这也就意味着一个CPU可以和更多的内存打交道;

       b. 8086CPU就出现了这样的瓶颈:

            i.   由于CPU太快效率太高,因此可以处理的内存空间数量巨大;

            ii.  巨大到超出CPU位数的限定,即内存空间的大小可以达到1MB(2的20次方),而CPU只有16位(即可以处理的地址数据的宽度只有2的16次方,64KB),远小于实际内存空间的大小;

            iii. 为了不受CPU位数太小的影响而浪费对那么巨大的内存空间(1M - 64KB)的管理,人为对CPU产生地址的部件做一些手脚,让它可以生成20位的地址,从而可以控制1MB大小的内存空间;

            iv. 这样就实现了用16位的CPU控制20位宽的内存地址空间,也就是说实现了16位的CPU接20位的地址总线;

       c. 有16位 CPU生成20位物理地址的方法:

            i.   方法很简单:一个16位地址左移四位再加上另一个16位地址形成一个20位地址;

            ii.  一般来说都是将左移四位的那个16位地址作为基准点,而将另一个16位地址作为相对于基准点的偏移量,而偏移量的变化范围就可以作为一个段的容量,当然这个容量的大小是人为规定的,是按照需要规定的,当然也是有上限的,由于偏移量是16位的,因此这个段的上限是2的16次方,即最多可以表示64KB的内存空间;

            iii. 左移4位的那个地址就是段地址,另一个地址就是偏移地址;

                 注意:并不是因为叫段地址就可以理解为CPU将内存分成大小为64KB的一个个段了,而仅仅是因为ii.原因才得来这个名字的,段地址只能看做一种基准(基点),对于实际内存地址空间中设备是如何划分的CPU完全不知情,因此段地址也叫做段基地址,这种称谓更加准确,有时也简称基地址和偏移地址,个人认为这种称谓更加合理;


4. 对程序分段:

    1) 当运行程序的时候需要将程序先装入内存,而在程序的内存空间中可以对程序进行分段,一般段与段之间的概念是松散的,即分段是根据人的意愿进行的,通常情况下是在逻辑上对程序分为代码段、数据段等部分,代码段一般用于存放程序的指令,并且是只读的(如果在程序运行阶段指令也可以修改则程序会乱套),而程序操作的数据则是可以修改的,因此数据段是可读可写的;

    2) 分段的方法:和C语言数组很像,要有一个基址(即该段的首地址),同时要有一个偏移指针,用于定位段中的某个字节处,就好比数组的随机访问(arr[15],arr就好比段基(即基址),而15就是那个具体的偏移量);

    3) 分段访问的实际实现方式:物理地址  =  段地址(基地址)×  10H(即左移4位)+  偏移地址

!左移是为了“扩容”:

       因为一开始CPU的长度有限(即寄存器的长度只有16位),对内存寻址的时候(寻址就是用CPU寄存器中的值指定内存单元中某个字节的位置)就只能寻址(2^16字节,CPU中的每一种值对应内存中一个字节的位置)64KB的空间,但通常内存很大,往往超过1MB,因此CPU能力不足,如果单单靠CPU来寻址则内存中会有很大一部分空间浪费,因此就采用对段基进行移位的方式来扩容;

       这样的话就只需要加一个20位的PC(Program Counter,即一个专门用于指向下一条指令的内存访问指针)寄存器来保存通过以上公式获得的地址就可以访问比CPU访问空间大的内存空间了!

    4) 因此可以将起始地址(即段地址)是10H倍数的一段连续的空间都可以看做一个段(但是段的长度不得超过64KB,因为偏移地址还是用一个16位的寄存器存储的),至于段的实际内容(即实际意义,诸如静态全局变量段之类的)完全由程序员自己定义;

    5) 对物理地址的描述方式:

        符号描述:段地址:偏移地址,比如2000:1F60

        文字描述:2000内存段的1F60单元,即实际物理地址为21F60

    6) 产生并传送20位物理地址的示意图:

    

             

原创粉丝点击