8086CPU内部有14个16位的寄存器, 按功能可以分为8个通用寄存器, 4个段寄存器和两个控制寄存器.
通用寄存器可以分为两类: 数据寄存器(AX, BX, CX, DX)和地址寄存器/变址寄存器(SI, DI, SP, BP)
8086CPU有4个16位数据寄存器:
8086CPU有4个16位的地址指针/变址寄存器:
寄存器BX SI DI SP 可以用作地址寄存器, 提供16位偏移地址, BX SI DI的默认段寄存器为DS, BP默认段寄存器为SS
8086CPU的段寄存器有4个:
在将这四个寄存器用作地址寄存器时, 他们只提供了16位的偏移地址.要形成20位的物理地址, 还需要有段寄存器提供段地址:物理地址 = 段地址 * 10H + 偏移地址
因为在8086中寄存器只有16位, 2^16 = 64Kb, 内存中一个字8位, 那么寻址能力就只有64KB, 也就是说内存最大只能有64KB, 显然, 这样的大小不符合当时人们对内存大小的需求. 所以采用了这种CS:IP,两个寄存器共同寻址的方式, 使得CPU能够寻址1MB的内存空间.
8086时代, CPU的工作模式是实模式, 段寄存器里面存放的是段基地址, 后来进入32位机时代, CPU就进入了保护模式,保护模式是指CPU从硬件机制上提供了用户程序对内存的访问限制,为多用户多任务的程序进行了彼此隔离,防止因某个程序的编写错误影响到操作系统和其它用户。保护模式下提供了修改段寄存器的保护/代码段的保护/栈操作时的保护/数据访问的保护等。在32位处理器中,在原有的CS/DS/ES/SS段寄存器的基础上对增加了FS/GS段寄存器,并且每一个16位的段寄存器都对应了一个描述符高速缓存器。 在32的保存模式下,段寄存器中存放不是段地址,而是段的描述符的索引号。
8086CPU有两个控制寄存器
控制标志:
存储器的分段和物理地址的形成
前面已经提到过, 物理地址由段地址和段内偏移地址两部分组成. 由于基址或变址寄存器为16位寄存器. 他们可以提供16位的偏移地址, 因此通过改变基址或变址寄存器可以寻址2^16 = 64kB的存储空间. 8086采用地址分段的方法, 是寻址范围扩大到1M字节.
在8086CPU系统中, 把1MB的存储器空间划分成若干个逻辑段, 每个段最多有64KB的存储空间, 各段起点选在能够被16整除的地址, 并将高16位的地址称为段地址, 因此1M字节的存储空间是相互覆盖的, 相邻段之间相距16个存储单元
相邻段之间为什么相距16个存储单元而不是16*n个单元, 相互覆盖是什么意思?
因为当程序开始执行是, 操作系统将程序由磁盘读入进内存, CPU会首先查找存储器可以被16整除的逻辑段首地址, 1. 他不能确定将要存放的逻辑段的大小, 但是必须确定各个段的首地址. CS段基地址必须由系统分配 2. 而且各个逻辑段不相互覆盖一定会造成空间浪费, 因为我们不能保证每个段的大小都是16的倍数, 而不是16的倍数, 段与段之间相互独立, 一定会有空间浪费