从16位进入保护模式小例子2个
简略写下过程.
16位也有保护模式,这里特指32位保护模式
1.保护模式中段寄存器不再使用段地址,而使用一个叫段选择子的东西,这个段选择子主要用来获取描述符
2.描述符(8个字节),描述一个段的信息,比如这个段从哪到哪(基地址, 界限), 是用来做什么的(TYPE)
3.在保护模式中, 访问一个段,必须先登记后访问, 下面2个例子都是登记在全局描述符表中(GTD)
3.1 全局描述符表就是一堆描述符存放的地方
3.2 加载此表需要6个字节, 高4字节放此表起始地址, 低2字节存放此表界限(最后一个字节), 因此界限的长度是最后一个字节加1
4.上面说到段选择子(2个字节), 高13位用来设置索引, 2^13 = 8192(个索引),低3位先忽略
4.1 全局描述符表需要加载6个字节, 高4字节是表的基地址(起始地址), 低2个字节是界限宽度
(界限:最大可访问的内存单元/ 最后一个有效可访问的字节)
4.2 界限:2^16 字节, 每个描述符8个字节, 全局描述符表最多可放 8192个描述符,
对应段选择子的8192个索引. 例如1号索引描述符的偏移: 1 * 8 + 全局描述符起始地址
2号索引: 2*8 +全局描述符起始地址
** 5.当给一个段寄存器赋值: mov ds, 0x10(二进制:10_000B) ; 0x10是段选择子, 当前索引1
5.1 用全局描述符表起始地址+ (1*8) , 检查这个地址有没有越界
5.1.1 越界指: 比如此表的界限是1 , 表基址:0 , 则 0 + 8 <= 0 + 1 ? 不越 : 越界;
5.2 把对应的描述符加载到段寄存器(当前是ds) 的描述符缓冲区
6. 在16位中默认操作数是2个字节, 到了32位默认操作数是4个字节
因此即使很多机器指令一样,在不同的运行环境中所译码的方式不同.
在例子1中的注释有解释
例子1 , 从实模式切换到保护模式.
例子2, 在保护模式中切换栈段,利用数据段修改代码段
例子1:
;描述符高4字节
;31 ~ 24 23 22 21 20 19 ~ 16 15 14~13 12 11 ~ 8 7 ~ 0
;段基址(24-31) G D/B L AVL 段界限 P DPL S TYPE 段基址(16-23)
;描述符低4字节
;31 ~ 16 15 ~ 0
;段基址(0-15) 段界限(16位)
;G: 段界限粒度, 0:1字节为单位 , 1: 4k为单位
;D/B: D(Default opeator size):代码段, B:栈段, 如置1表示使用32位操作数, 0则使用16位
;L: 64位
;P: 是否在内存中
;DPL: 权限
;S: 系统段/代码,数据段
;Type: 代码还是数据
;在保护模式中不再把段地址赋值给段寄存器
;而是把段选择子赋值给段寄存器 , 比如 mov ax,0x10, mov ds,ax
;具体过程
;1. 通过gdtr寄存器的地址找到gdt表所在地址
;2. 根据提供的0x10所在的索引找到对应的gdt描述符
;3. 判断此描述符是否在 gdt表 所允许的界限之内, 如果不在界限之内则中断