1、什么是内存的物理地址
我们通过8086CPU来说明内存地址是如何形成的。
首先我们要了解物理地址,当CPU需要访问一个内存单元时,需要给出内存单元的地址,而每一个内存单元在物理内存空间中都有一个唯一的地址,即可以通过这个地址定位到内存单元,而这个地址即为物理地址。
CPU通过地址总线将一个内存单元的物理地址送入存储器,而后CPU便可以通过这个物理地址来访问这个物理地址所指向的内存单元了。
2、内存物理地址在CPU中如何形成
首先,我们知道8086CPU的地址总线是20根,即每次都可以传输20位的地址,从而寻址能力有2^20,也就是1MB的大小。但是,8086CPU的寄存器只有16位,也就是在8086CPU的内部,处理、传输、暂存的地址都只能是16位,即8086CPU不能完整的保存下一个物理地址(物理地址为20位)。
如果以最简单的方式(即直接用16位寄存器来保存物理地址)的话,寻址能力只有2^16,也就是64KB大小,难道8086CPU只能支持64KB大小的内存吗?
当然不是,8086CPU在这里采取了一定的措施,使其寻址能力达到1MB。
8086CPU在内部把两个16位的地址进行合成,从而形成一个20位的物理地址,8086CPU的寻址能力便可以达到1MB。具体是如何将两个16位的地址合成为一个20位的物理地址的呢?
当CPU在访问内存时,其会使用一个16位的基地址,然后再使用一个16位的偏移地址,通过将两个地址传入8086CPU的地址加法器中进行合成,即可以构造出20位的物理地址。
至于合成的方式如下:
将段地址左移4位,形成基地址,然后将基地址和偏移地址相加便形成了20位的物理地址。如下图:
3、内存段是什么
其实在物理内存中是没有内存段这一概念的,内存段的概念来自于CPU中的段寄存器。
我们将若干个地址连续的内存单元看做是一个段,通过将一个段地址左移4位形成基地址,然后通过这个基地址来定位这个段的起始地址,最后再通过偏移地址便可以精确定位到段中的内存单元了。
由于内存段的起始地址是一个段地址左移4位,所以内存段的起始地址肯定是16的倍数。而且一个内存段内部的内存单元只能通过偏移地址来定位,而偏移地址为16位,所以一个段的长度也就是2^16也就是64KB的大小。
在编程时,可以将一段内存定义成为一个段,分为数据段,代码段,栈段这三种类型的段。具体如下:
- 数据段
存放我们所需要使用数据的内存段(当然段起始地址肯定是16的倍数,并且段长度<=64KB)。
- 代码段
存放代码(也就是指令)的内存段。
- 栈段
我们将一段内存当做栈来使用就称为栈段。
一个简单的例子:
MOV BX, 1000H ;
MOV DS, BX???? ;向DS段寄存器传入1000H段地址。
MOV AX, [1234H]?;将内存地址1000H:1234H(即11234H)中的值读到AX寄存器中。