
大家好,感谢大家支持!
在网上,前几年讨论的比较多的是进大厂,近几年讨论的比较多的是如何搞副业。人家说,在身体好的时候去锻炼身体;在有钱的时候去攒钱;在有工作的时候去做一份副业;毕竟现在不确定越来越多了!不知道,大家怎么看呢?
在我们所了解的 Intel 早期 段描述符,是那个只支持 1M 寻址的 8086,那会儿,它只有实模式,不过我想在有保护模式之前可能并没有实模式这个概念吧。在 80386 时,为了各种数据、代码的隔离,就有了保护模式这个概念。它在设计上为了兼容早期的 8086,把之前的 1M 的寻址称为实模式。
在实模式下,寻址依靠 段地址 + 偏移地址 的方式进行寻址,段地址 是由段寄存器给出,段寄存器 的长度是 16 位的。而在保护模式下,段寄存器依然存在,而且依然还是 16 位,但是它的作用和在实模式下的作用却截然不同了。
在实模式下,段寄存器中给出了段的地址;在保护模式下段寄存器被称作段选择子。段选择子实际是给出 段描述符 的索引(这个描述不准确,应该是 段描述符 映射到高速缓存后的索引)。
这里给出 段描述符 和 段选择子的结构,结构如下:


上面两个图来自 Intel 手册,上图是 段描述符 的结构,下图是段选择子的结构。从上图得知,段描述符 是 64 位的结构,段选择子是 16 位的结构;而段选择子真正用来索引的部分是从第 3 位开始的,而它的第三位不是用来进行索引的。
看到这里,没有什么问题,一切都好!
到这里,就该上代码了!
; GDT
; 段基址 段界限 段属性
SYS_GDT: Descriptor 0, 0, 0
SYS_DESC_CODE: Descriptor 0, 0ffffh, 0
SYS_DESC_DATA: Descriptor 0, 0ffffh, 0
SYS_DESC_STACK: Descriptor 0, 0ffffh, 0
; end of definition gdt
; 段选择子
SelectorCode equ SYS_DESC_CODE - SYS_GDT
SelectorData equ SYS_DESC_DATA - SYS_GDT
SelectorStack equ SYS_DESC_STACK - SYS_GDT
; END of [SECTION .gdt]
上面代码随便定义了一些 段描述符 和 段选择子,段选择子的值分别是由 段描述符 项的地址减去 段描述符 的首地址就可以得到了(段描述符 的第 0 项是不使用的)。
段描述符 的项是 8 字节的大小,那么 段描述符 的项减去 段描述符 的首地址,那么得到的值应该是 8、16、24 这样;可是不是说,选择子中的值是 段描述符 映射后的索引值么?那不应该是 1、2、3 这样?
到这里,就是觉得这个设计精妙之处啊!再来看下段选择子的结构。

看!低 3 位是另做它用的,真正当做索引的值是从第 3 位开始的!
那么,把上面 段描述符 的项减去 段描述符 的首地址得到的值,也就是 8、16、24 这些值右移 3 位以后是多少呢?就是 1、2、3 了!
看到这里是不是就感觉到,原来段选择子的设计还能这样啊!因此,我想说的是,段选择子这样设计,是有意为之呢,还是巧合呢?
最后,分享一些学习资料吧!有需要的收好!
DDD领域驱动架构设计-复杂业务应对之道 : https://pan.baidu.com/s/112HwUAigAyps9c7F7gFdCA?pwd=dp5v
亿级电商订单系统-架构设计评审与验证: https://pan.baidu.com/s/1QJEJH2pH6gzhnWSWtg40bA?pwd=zi99
三大高并发架构设计案例实战-大会员系统,应对高并发读: https://pan.baidu.com/s/1lsrT46XWqzKZLk0X-4NhAQ?pwd=fpad
游戏服务器开发:https://pan.quark.cn/s/f2561aafcdae
关注我,写小白也能看懂的文章!
你的点赞,是对我的支持!感谢!