我们注意到,“段地址”这个名称中包含着“段”的概念。这种说法可能对一些学习者产生了误导,使人误以为内存被划分成了一个一个的段,每一个段有一个段地址。如果我们在一开始形成了这种认识,将影响以后对汇编语言的深入理解和灵活应用。
其实,内存并没有分段,段的划分来自于CPU,由于8086CPU用“基础地址(段地址x 16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。如图2.9所示,我们可以认为:地址1 OOOOH-100FFH的内存单元组成一个段,该段的起始地址(基础地址)为10000H,段地址为10000H,大小为100H;我们也可以认为地址10000H-1007FH, 10080H-100FFH的内存单元组成两个段,它们的起始地址(基础地址)为:10000H和10080H,段地址位:1000H和1008H,大小都为80H
以后,在编程时可以根据需要,将若干地址连续的内存单元看作一个段,用段地址x16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。有两点需要注意:段地址x16必然是16的倍数
,所以一个段的起始地址也一定是16的倍数;偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB
内存单元地址小结
CPU访问内存单元时,必须向内存提供内存单元的物理地址。8086CPU在内部用段地址和偏移地址移位相加的方法形成最终的物理地址。
思考下面的两个问题。
(1)观察下面的地址,你有什么发现?
物理地址 段地址 偏移地址 21F60H 2000H 1F60H 2100H 0F60H 21F0H 0060H 21F6H 0000H 1F00H 2F60H
结论:
CPU可以用不同的段地址和偏移地址形成同一个物理地址。
比如CPU要访问21F60H单元,则它给出的段地址SA和偏移地址EA满足SA X 16十FA=21F60H即可。
(2)如果给定一个段地址,仅通过变化偏移地址来进行寻址,最多可定位多少个内存单元?
结论:偏移地址16位,变化范围为O-FFFFH,仅用偏移地址来寻址最多可寻64KB个内存单元。
比如给定段地址1000H,用偏移地址寻址,CPU的寻址范围为:10000H-1FFFFH
在8086PC机中,存储单元的地址用两个元素来描述,即段地址和偏移地址。
“数据在21F60H内存单元中。”这句话对于8086PC机一般不这样讲,取而代之的是两种类似的说
法:
①数据存在内存2000:1F60单元中;
②数据存在内存的2000H段中的1F60H单元中。
这两种描述都表示“数据在内存21F60H单元中”。
可以根据需要,将地址连续、起始地址为16的倍数的一组内存单元定义为一个段。
检测点2.2
(1)给定段地址为0001 H,仅通过变化偏移地址寻址,CPU的寻址范围为______到______。
(2)有一数据存放在内存20000H单元中,现给定段地址为SA,若想用偏移地址寻到此单元。则SA应满足的条件是:最小为_______,最大为______
提示,反过来思考一下,当段地址给定为多少,CPU无论怎么变化偏移地址都无法寻到20000H单元?
段地址拓展补充
1、把地址 10000H ~ 100FFH 的存储器单元,当做一个段。
该段的起始地址为10000H,段地址1000H,
(为啥是1000,不是10000)
?
因为段地址是 4 位16进制数,不可能是 5 位。
大小为100H,(为啥是100,真的想不明白啊)
计算如下:
100FFH -10000H + 1 = 100H
你想想,200,到 299,共有 100 个数吧 ? 就是这么算出来的。
---------------------------
2、他们的起始地址为10000和100080,段地址为1000和1008,大小都为80h,数都不是同一个数,为啥大小都是 80 呢?
计算如下:
1007FH -10000H + 1 = 80H 100FFH -10080H + 1 = 80H
它们是相同的。
---------------------------
1、8086CPU中的段寄存器最多只能存储4位16进制的数字(范围0-ffffH),10000H是5位16进制数,段寄存器放不下的。
2、换算成物理地址时,段地址寄存器存储的值要乘以16。
10000H-1007FH、10080FH-100FFH 这两个段的长度就是:末地址-首地址+1 1007F-10000+1=80H 100FF-10080+1=80H
80H是这两个段的长度,俩段都有80H个内存单元。