玩儿转C语言:系统内存模型之实模式和保护模式

来源:互联网 发布:中国式父母 知乎 编辑:程序博客网 时间:2024/05/20 15:13

       要想对C语言有一个深入的理解,就不得不说它赖以生存的环境,这里简要介绍一下系统内存模型。内存模型,就不得不说业界知名的Wintel联盟,到底是谁选择了谁?又是谁成就了谁?反正已成事实鬼才知道!

          关于IntelX86家族的发展历史这里不想赘述,无非就是:字长越来越大(4位 -> 8位 -> 32位 -> 64位);频率越来越快(30MHz -> 600MHz -> 998MHz -> 2.2GHz);芯片制程越来越先进(900nm -> 600nm -> 300nm -> 90nm -> 32nm -> 28nm);内核越来越多(单核 -> 双核 -> 四核 -> 八核);指令集越来越多(浮点运算、SSE等)架构越来越新(英文太怪,没记住);性能越来越高(什么百万条指令每秒的)。

       学过X86汇编的人,都应该对里面讲到的段地址和段内偏移印象深刻,有没有想过为什么Intel的工程师要弄这么一个“变态”的设计,8086处理器本来就是16位的地址,按理说只能访64KB的内存,可是我们“聪明”的工程师一定要别出心裁,用两个16位的地址,组成一个20位的地址,访问1MB的内存。因为处理器的设计要考虑向后兼容,为老型号处理器设计的程序,要能在新型号处理器上运行才行。因为8085用的是16位地址访问64KB内存,为了改动最小,那8086就只能这么设计了。但是,这种设计暂时给Intel节省了成本,赢得了市场,可是长远来看,Intel不得不一次次焦头烂额的为这一次“聪明”买单。因为既然确立了这个基本的地址模型,后续的80x86处理器不得不延续这种做法,否则就会导致不兼容而失去市场,现实给技术创新带上了镣铐!

       如果一切到此结束,对技术人员来说或许是最好的结局。但我们总是希望做到“更小、更快、更便宜”,几十年来摩尔定律一直在指引着我们。我们对内存空间的需求越来越强烈,内存也越来越大,从80286起Intel提出了虚拟模式(virtual mode)的概念。在虚拟模式中,段寄存器中的值并不与偏移地址相加,而是指向一个存放实际段地址的表,该值是表中实际段地址的索引,这种16位的地址模式也被称为保护模式(protected mode)。其实刚开始没有实模式和保护模式的概念,只是后来我们改变了地址模式的策略,又为了向下兼容,就不得不区别对待这两种模式,好让两种模式下的程序都能正常运行。如下图所示(网络截图,懒得画):

         实模式:段寄存器中的16位数据左移4位,变成20位数据,但是低4位是0存储颗粒度太大,需要加上偏移地址,共同构成有效的20位地址,这就实现了实模式下利用16位地址访问20位数据空间的构想。数据空间一下子由64KB扩大到了1MB,在当时来不得不说是个奇迹,回过头来看连首歌都存不了呵呵。

         实模式优缺点:实模式在当时有效的解决了存储空间的问题,资源消耗最小,又达到了目的。但随着技术的发展,我们对空间的要求越来越高;而且在实模式下,用户进程可以随意访问物理内存,风险极大,就需要要一个有效的手段来对用户进程进行限制和监管,就需要有对应每个进程的“监管信息”,这些信息如何存储?在实模式下遇到了困难。     

         保护模式:相对实模式而言,也是为解决实模式下问题而生。在保护模式下,“段寄存器”中存放的不再是段地址,而是“段选择符”(是一个“段描述符”的偏移)。1、实模式下无法进行大空间访问(16位大小),那好在保护模式下通过“段描述符”(存在与内存中)来存放基地址,段描述符里面的基地址就没有16位大小的限制了,空间问题完美解决。2、实模式下无法进行进程监管,监管信息无处存放,那好在保护模式下,“监管信息”存放到段描述符中(内存中),而且还没有信息量大小的限制,当进程访问内存时,直接通过段选择符找到段描述符,就能得出访问基地址(位数不限)和监管信息(信息量大小不限)。最后,基地址+偏移就是进程需要的物理内存地址。注意:GDT和LDT是全局/局部描述符基地址,这里可以认为就是一个存储基地址的寄存器。

        保护模式优缺点:完美解决实模式下的空间限制和监管难题,实在想不出有什么缺点,如果实在要说,那就是需要占用一部分内存空间存放这些信息,而且访问物理内存需要多一层数据访问。但是这点性能损失跟它带来的好处来比,是值得付出的。

思维逻辑探秘:

         1、在分析这两种模式下的差别和指导思想时,忽然发现我在做产品时不就是这么做的吗。本来只负责一款“固定界面显示”产品的实现,但是公司想要在这个基础上实现多语言界面显示,而且内部逻辑不变,只修改显示层。可是数据结构都已经做好,如果是一款固定界面,这些显示层的属性信息只存在于MCU的ROM中即可;如果是多语言界面,那么这些属性信息就要支持动态修改,要存储到外部Flash中,在ROM内部存储非常少的各个属性字段的偏移,初始化时根据偏移调取对应的属性字段,来实现多语言界面的切换,类似于这里的实模式和保护模式。

         2、如果把整个存取过程比做“信息链”的话,实模式的信息链最短也最高效,但受限于处理器本身字长,扩展能力较弱;而保护模式人为的增加了一层“信息链”,牺牲了一部分效率,却实现了处理器字长的无关性,想要多少个字节的地址,完全取决于段描述符的大小,扩展性极大。

        3、对于“监管信息”的存储,也是同样的道理,人为增长的“信息链”可以把监管信息放进来,来对进程权限进行限制。在实模式下,进行如果想操作物理内存,只需要知道段地址和偏移,简单运算就可以得到地址;在保护模式下,需要根据偏移找到描述符,系统根据描述符里边的属性信息,决定要不要让进程得到物理地址,多了一层限制。生活中又何尝不是如此,管理层的监管层次越多,效率就越低,限制就越严格!

原创粉丝点击