首页 > 代码库 > (转)存储器分段和地址计算

(转)存储器分段和地址计算

存储器分段和地址计算
1. 存储单元的地址和内容
    在8086 CPU系统中,以字节为单位线性地组织存储器。一个字节就是一个
存储单元,为了标识和访问每个存储单元,给每个存储单元规定一个编号,即
存储单元的地址
    存储单元的地址用二进制无符号数表示,从0开始,顺序加1,则n位二进制
数可以表示2^n个存储单元的地址。
    一个存储单元中存放的信息称为该存储单元的内容。当将一个字存放到存
储器时需要占用两个连续的字节,系统规定:把一个字存放到存储器时,低字节
存放在地址较低的字节单元,高字节存放在地址较高的字节单元,
    例如:地址33451H中的字单元的内容为5612H

_________________________00000H   
    |    ......        |
    |_______________________|33450H
    |    34H        |
    |_______________________|33451H
    |    12H        |
    |_______________________|33452H
    |    56H        |
    |_______________________|33453H
    |    29H        |
    |_______________________|
    |    ......        |
    |_______________________|

    这种存储原则称为“高高低低”原则。对于由四个连续字节构成的双字单元,
也使用同样的原则,例如地址33450H的双字单元中存放着数据29561234H。

2. 存储器的分段
    8086 CPU有20根地址线,可直接寻址的地址空间为2^20=1M字节,即存储单元
的物理地址是20位的二进制无符号数,范围为00000H~FFFFFH。
    但是,8086 CPU内部的算术逻辑单元只能进行16位运算,而且存放存储单元
地址偏移的指针寄存器(SP、BP、SI、DI、BX)均为16位,无法直接寻址1MB物理
地址。为此,把1MB地址空间划分成若干逻辑段,每个逻辑段满足如下条件:
    (1)逻辑段的开始地址必须是16的倍数——与段寄存器长16位有关
        即逻辑段的起始地址最后四位必定为0000
    (2)逻辑段的最大长度为64K——与指针寄存器长16位有关

3. 物理地址的计算
    根据存储器的逻辑分段,如何计算实际的物理地址?很明显,逻辑段的起始
地址是16的倍数,即逻辑段的起始地址均具有如下形式:
        xxxxxxxxxxxxxxxx0000B = XXXX0H
    这种段起始地址可以压缩为XXXXH,称为段值,即段起始地址等于段值成语16。
    而要访问的存储单元总属于某个段,将存储单元地址与所在段起始地址的差
称为段内偏移,简称偏移。在给定段内,通过偏移完全可以确定要访问的存储单元,
因此在整个1MB地址空间中,
        存储单元的物理地址 = 段起始地址 + 段内偏移
                           = 段值 × 16 + 段内偏移
                           = 段值 : 偏移    (简化表示)

    采用“段值:偏移”构成逻辑地址后,段值由寄存器给出,偏移可以由指令指针IP、
堆栈指针SP、以及其它可用作存储器指针的寄存器(SI、DI、BX、BP)给出、或者直接用
16位数给出。指令中不使用物理地址,而使用逻辑地址,由CPU的总线接口单元BIU根据
段值和偏移自动计算出物理地址。

4. 段寄存器的引用
    8086 CPU有四个段寄存器,可保持4个段值,故可同时使用4个段,但四个段各有分工。
每当需要生成物理地址时,BIU会自动引用特定的段寄存器来计算物理地址。
    (1)取指令时,BIU自动引用代码段寄存器CS,再加上指令指针IP的16位偏移,得到
         指令的物理地址;
    (2)当涉及堆栈操作时,则自动引用堆栈段寄存器SS,再加上SP的16位偏移,得到
         堆栈操作所需的物理地址;当偏移涉及BP寄存器时,默认引用的段寄存器也是
         堆栈段寄存器SS;
    (3)在存取存储器中的操作数时,自动选择数据段寄存器DS或附加段寄存器ES,再
         加上16位偏移,得到操作数的物理地址。此时的16位偏移,可以说包含在指令
         中的直接地址,也可以是某个16位存储器指针寄存器的值,也可以是指令中的
         偏移再加上存储器指针寄存器的值,主要取决于指令的寻址方式。

    在不改变段寄存器值的情况下,寻址范围最大是64KB。若某程序使用的总存储长度
(包括代码、堆栈、数据区)不超过64K,则整个程序可以合用一个段;若某程序的代码
长度、堆栈长度、数据区长度均不超过64KB,则可在程序开始处分别给DS、SS等段寄存
器赋值;若某程序的数据区长度超过64KB,则要在两个或多个数据段中存取数据,此时
需要改变数据段寄存器的段值。

转自:http://blog.csdn.net/yanxiansheng/article/details/7183042

(转)存储器分段和地址计算