最根本的原因是8086空有20位地址线却只有16位寄存器
当然在解释这句话之前很有必要先说清楚分段机制,首先8086的分段机制是不同于普通的分段机制的。对于普通分段机制来说,是用以解决重定位问题的——对于你自己的代码,你确实可以自己安排一个可用的内存地址让处理器加载你的程序到此处(这称为绝对地址),但出于对他人加载你的程序/你加载他人的程序的考虑,为了使你的程序在任一个可用的内存地址上加载时都可以正常执行,在编写程序时就需要使用逻辑地址(或者说是相对地址),那么使用相对地址为什么能让别人加载你的程序也能正常执行呢?因为当程序被加载时,这些程序代码内被安排好的相对地址就可以根据程序实际被加载的地址来重新计算——这就是重定位。
分段机制通过段地址加上偏移地址的方式解决了重定位的问题——举个例子,你在程序代码内声明了3个存储单元打算留给变量(从上面讨论中我们在声明时应避免使用像0xC3210,xC322,0xC323这样的绝对地址,而是应该使用像0x0000,0x0001,0x0002这样的相对地址)分别是相对于改代码段开头的距离0处,距离1处和距离2处的3个存储单元。然后一旦程序被处理器加载到某个可用地址比如0xXXX0处,这样经重定位计算后程序会在0xXXX0,0xXXX1,0xXXX2处声明3个存储单元地址给变量。这里的好处一是避免了访问到非法的地址空间,再就是能使得处理器在内存任何位置处加载该程序都能使得程序拥有正确可用的地址空间。在这个例子中段地址就是0xXXX0,偏移地址就是0x0000,0x0001,0x0002——这便是分段机制
这就是需要分段机制的原因,但是8086在实现分段机制时却有个麻烦——理论上20位地址线可以寻址
220=1048576=0xFFFFF(15*65536+15*4096+15*256+15*16+16*1)(以十六进制表示的物理地址最多是5位)
但8086实际上却只有16位寄存器,16位寄存器最大可以表示的地址空间为
216=65536=0xFFFF(15*4096+15*256+15*16+16*1)(以十六进制表示的物理地址最多是4位)
你可以看到以现有的寄存器无法访问到理应能寻址到的大部分地址空间,因此8086的分段机制是段地址先乘上16或者说左移4位(左移1个二进制位相当于乘上21,这里相当于乘上24)再加上偏移地址
这就是8086需要这样的分段机制的由来