首先我们要清楚以下几个问题?
①为什么要分段?
答:我们的地址总线是20位的,可以寻址的个数是2的20次方,也就是1M,而寄存器只有16位,一次只能探寻2的16次方个地址,也就是64K. 那我们就不能充分利用地址总线的寻址能力了.
②怎么分段,思路在哪里?
说白了,就是地址总线的1M的地址,我们寄存器的16位所能分配地址只有64K,不能一一匹配寻址.
如果要强行匹配的话,就是2的20次方除以2的16次方等于16,我们寄存器所能表示的每一个操作数都有16个地址需要表示,那干脆就把这地址总线的1M地址分成2的16次方个段,每一段有16个地址.
这样我们就实现了,充分利用总线.
②数学问题,那寄存器段地址和偏移地址如何运算,才能送入地址总线
寄存器是16位,地址总线是20位,我们差4位,也就是需要地址向左偏移4位,然后加上偏移地址就可以了.
③会不会出现溢出啊?因为段地址是16位,偏移地址说白了也是16位寄存器,会不会出现偏移地址过大,然后加起来的地址也可以用别的段的段地址加偏移地址来表示?
答:我们首先要理解一个问题,我们是在一段空白的内存里面来分配地址的,段只是我们自己所定义的概念,到最后cpu还会把我们的段地址和偏移地址处理成20位的地址总线上的地址,至于我们如何分配段地址和偏移地址是我们自己的事情,程序不会崩溃.
但是我们要知道,我们分配段的目的,就是要将内存分配的井井有条,如果我们的偏移地址过大从而跳到别的段,那有可能改变别的段的数据和操作.当然那是不可取的
④明明偏移地址是16位的寻址能力,为什么我们上面分配每个段只有16的偏移地址?不能分配更多吗?
答:我们首先要明白第一个问题,我们的寄存器想要的是表达20位的地址,解决地址总线寻址不充分的问题,从而引出了段的概念,说白了,段*16加上偏移地址就是一个20位的地址,至于担心的溢出问题,详见问题②.
当然我们可以让每个段分配更多的偏移地址,因为我们有那个能力,偏移地址是16位的,当然我们可以让一个段 分配2的16次方偏移地址, 仅限这一个段,为什么?详见问题②,我们现在的确没有考虑让每个段的偏移地址个数都相同,但是我们是可以让一块内存,表示一个段的内存,大小最多为64K,(注意:我们的寻址能力代表我们能占用的内存数)没问题,可以实现,但是就是不建议罢了,充分理解上面几个问题就知道,不然就不能把20位地址全表示完了,还会出现溢出混乱.
我们的段地址当然是16的倍数,因为我们偏移了,但是我们的偏移地址过大的话,经过cpu运算,就会窜到别的段,但是没有问题,可以实现,见问题③. 如果别的段没有内容还可以,但是有内容呢?
所以,段的偏移地址可以把16位的寄存器全用上,访问64K的地址,但是不是所有的段都可以是64K,参考问题②.