8086和i386的区别和联系

在运行i386模式之前, CPU会先运行在8086模式下
在8086模式下, 寻址范围是1M, 寻址方式结合段寄存器, p_address = (段寄存器 << 4) + offset
在i386模式下, 一个寄存器可以存放32位地址, 不需要段寄存器, 但是为了兼容和保护, 这里的段寄存器存放的是段选择子, 实现的是虚拟地址
虚拟地址的好处
直接使用物理地址无法同时运行多个程序, 如果对每个程序空间进行划分, 如果程序数量是无限的, 不切合实际
如果使用虚拟地址, 不同程序可以有相同的虚拟地址, 可以把相同的虚拟地址映射到不同的物理地址, 方便开发的同时保护了内存
分段机制

每个进程有它的虚拟地址空间0 ~ 4G, 每个进程有个描述符表, 描述符描述了每个段的起始位置, 大小和权限
访问虚拟地址的时候, 将虚拟地址作为offset地址, 实际得到的物理地址是段基址 + offset, 段选择子放在段寄存器当中, 相当于段描述符表的下标
这样就可以将不同进程的相同地址(虚拟地址)映射到不同的物理地址
如果一个进程使用的内存比较多, 可以先将一些不用的内存移动到磁盘上, 当前程序使用交换的这块内存, 这样每个进程都认为自己有4G的内存空间
i386的地址分类

如果开启了分页机制, 程序使用的是虚拟地址, 经过分段机制后得到的是线性地址, 线性地址经过分页机制后得到的才是物理地址

分页机制可以将权限设置的更详细, 现代CPU一般使用分页机制, linux为了在x86只使用分页机制将虚拟地址和线性地址做一一映射, 也就是每个虚拟地址等于线性地址, 如果虚拟地址是0x10, 那么线性地址就是0 + 0x10也就是0x10
i386分段详解

需要一个描述符表, 存放在内存当中, 也就是一个结构体数组, 数组的每一项就是一个段描述符, 段描述符是64位的

设置一一映射
描述符表的地址

地址在GDTR寄存器中, GDTR寄存器的内容初始化也在内存中

后面在使用过程中, 将该位置的数据加载到GDTR寄存器, 这样CPU可以通过GDTR寄存器找到描述符表

在内存中设置相应的段选择子, 后面加载到CS, DS寄存器中, 这样CPU就可以根据这两个段选择子找到段描述符, 获取到段基址 + IP寄存器的偏移地址

京公网安备 11010502036488号