开始地址 | 内存区 |
00000h | 中断向量表 |
00400h | BIOS数据区 |
00500h | DOS数据区 |
| DOS驻留程序 |
| 可用空间 |
A0000h | 图形模式视频缓冲区 |
B0000h | 单色字符模式视频缓冲区 |
B8000h | 彩色字符模式视频缓冲区 |
C0000h | VGA BIOS地址 |
C8000h | ROM扩展,系统BIOS地址 |
FFFFFH | 64K高端内存 |
从A0000h开始是硬件使用的地址,在内存低端共640KB,去掉中断向量表、BIOS数据区和DOS操作系统,应用程序大概可使用600KB
80386的分段管理机制
80386的段寄存器是16位的,无法放下保护模式下的64位段描述符。段描述符用来描述段的详细信息,如段的大小、位置和使用情况。段描述表是放在内存中的。
保护模式下,段由3个参数来定义:段基地址+段界限+段属性。其中段基地址为32位。段界限为20位,在段属性中可以选择段界限的单位为1字节或者4K。
80386中一个48位的全局描述符表寄存器GDTR+1个16位的局部描述符表寄存器LDTR
GDTR指向全局描述符表GDT,包含操作系统的代码段、数据段、和堆栈段的描述符以及各任务的LDT段。
LDTR指向局部描述符表LDT,每个任务有单独的LDT。它包含每个任务的代码段、数据段和堆栈段以及该任务的门描述符,如任务门和调用门描述符
16位的段寄存器只有高13位表示索引值,剩下的3为数据中,第0,1位表示程序的当前优先级RPL,第二位TI位表示段描述符的位置,TI=0表示在GDT中,TI=1表示在LDT中。
虚拟地址格式:XXXX:YYYY YYYY
来分析一下流程:注意这里的索引其实是偏移量,线性地址是32位。
第一种情况:
l 看XXXX中的TI位,如果是0,则从GDTR中获取GDT的基地址
l 然后以XXXX中的高13位作为索引在GDT中获取段描述符,那么就得到了段的相关信息。
l 然后再根据YYYY YYYY就可以找到相应的线性地址了。
第二种情况
l 如果是1,则从GDTR中获取GDT的基地址
l 以LDTR中的高13位作为索引在GDT中获取描述LDT段的描述符。
l 根据这个这个描述符获取LDT段
l 以XXXX中的高13位作为索引就可以找到在LDT段中对应的描述符
l 根据这个描述符+YYYY YYYY就可以找到对应的线性地址