要点回顾
- 段寄存器的值是通过段描述符填充的。
- 但是段描述符只有64位,如何从64位变成80位?
段描述符的结构
P位
P位位于高4字节下标为15的位置。
- P = 0:段描述符无效。
- P = 1:段描述符有效。
通过指令将段描述符加载至段寄存器的时候,CPU第一件事就是检查该段描述符的P位。
如果P位等于0,那么其他的检查就不做了。只有当P位为1的时候才会做后续的其他检查。
G位
G位位于高4字节下标为23的位置。
在了解G位之前,先来回顾一下段寄存器的结构。
段寄存器的结构
struct SetMent
{
WORD Selector; // 16位Selector 可见部分
WORD Attributes; // 16位Attributes 表示当前段寄存器是可读还是可写
DWORD Base; // 32位Base 表示当前段寄存器是从哪里开始的
DWORD Limit; // 32位Limit 表示当前段寄存器整个的长度有多少
}
段寄存器结构与段描述符的对应关系
Attributes由1部分组成:
- 高4字节的第 8-23位。
Base由3部分组成:
- 高4字节的第 0-7 位。
- 高4字节的第24-31位。
- 低4字节的第16-31位。
Limit由2部分组成:
- 高4字节的第16-19位。
- 低4字节的第 0-15位。
- Limit两部分加起来一共20位,如果转换为16进制:FFFFF,5个16进制的数字。
- 一个16进制的数字,对应4个二进制的数字。
- Limit正常情况下是32位,32位对应8个16进制的数字,无法填充。
如果想要正确填充,就需要看G位:
- G = 0。
- 此时Limit的单位是字节。这意味着只需要在前面补充0即可。如前面的FFFFF,补充0后变成000FFFFF。
- 如果G = 0时,Limit的上限是(5个F)FFFFF。
- G = 1。
- 此时Limit的单位是4KB,而不是原来的字节。1KB = 1024,4KB = 4096,地址计算从0开始计算,所以需要再减去1,得出4095,转换为16进制刚好是FFF。
- 如果G = 1时,Limit的上限是(8个F)FFFFFFFF。
总结:
- 如果G位为0,那么在前面添加3个0,也就是G位为0时,Limit的上限是000FFFFF。
- 如果G位为1,那么在后面添加3个F,也就是G位为1时,Limit的上限是FFFFFFFF。
举例说明
- 例如上图中段寄存器ES
- BASE是0,段选择子是0x2B,而上限(Limit上限/界限)是0xFFFFFFFF。
- 那么说明结构体加载的段描述符中的G位,是1。
- 其他段寄存器如CS、SS、DS、GS也是如此。
注意
- 段寄存器FS比较特殊,该段寄存器与操作系统的线程有关,拆分后的值与段寄存器中的值不符合。
- 故在进行实验或练习时暂时不要对FS段寄存器进行操作。
练习
分析段选择子为0x1B、0x23对应的段描述符,并将内容填写到段寄存器结构体中。
今天的文章段描述符表_临时符属性上下浮动分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/83541.html