其实段的来历比较简单:在dos时代(硬件方面是386以下),因为16位的处理器无法访问(寻址)20位的地址总线提供的1M内存,于是就使用分段的办法解决:每个段64K,(按照最大段来计算,多少段?1M/64K=16个段),这样就可以利用两个16位寄存器来寻址这20位的1M内存(虽然,是浪费了12位宝贵的寄存器位数,两个16位寄存器合起来的寻址能力是2^32=4G,现在只需利用其中2^20的寻址能力,但却变相实现了利用两个16位寄存器来寻址20位1M的内存的功能),因此可以利用一个寄存器来表示段地址(那个64K的段从哪儿开始),另外一个16位的寄存器来表示你要访问的数据在该64K的段内的什么地方。起前一个功能的寄存器就叫段寄存器(按段寄存器所指的段的用途来分,这些段寄存器又分为:CS、DS、SS、ES等。而后一个功能则一般通过通用寄存器来实现的,通常后面这个用来在段内寻址的地址就叫做段内偏移(offset),它也是16位的寄存器。
在具体寻址的时候是如何计算的呢?段寄存器和段内偏移地址直接相加?不是的,因为那样最多能够达到17位的寻址能力。正确的做法是将段寄存器左移4位,然后加上段内偏移地址,这样就得到了20位的地址了,使用则20位地址就能够实现1M的存储空间寻址。
现在32位平台下的这些理论已经不实用了,因为32位的CPU的寻址能力达到4G,则就是为什么32位的操作系统说它支持最大4G内存,而32的应用程序也说它自己有4G的存储空间寻址能力,(虽然背后引入页面文件等等新的理论),但是理解16位的分段,却可以帮助我们理解这些更加复杂的32寻址方式。
[此贴被 憨狗(hackgou) 在 10月10日13时48分 编辑过]
|