0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

操作系统之CPU与实模式(下)

jf_78858299 来源:码农的荒岛求生 作者:陆小风 2023-02-15 14:55 次阅读

分段式内存管理

我们知道,程序的内存从内容上可以分为存放机器指令的代码区域、存放全局变量的数据区域、保存函数运行时信息的栈区等,显然我们可以将程序按照这种划分进行分段管理,段内使用相对地址,这样无论这些段被加载到内存的哪个区域我们都能方便的计算出正确的物理内存地址。

图片

我们将各个段在内存中的起始地址放到专用的寄存器中,X86 CPU中有这样几个段寄存器,CS、DS、SS以及ES,这些寄存器有什么用呢?这几个寄存器就用来存放各个段在内存中的起始地址(暂且这样理解,稍后你会发现这些寄存器的真实用法):

  • 保存机器指令的区域,这个区域就是我们所说的代码段(Code Segment),因此我们可以使用一个寄存器来专门指向代码段,这就是CS寄存器的作用,CS也是Code Segment的缩写。
  • 同样的道理,程序运行起来后还有专门的区域用来保存数据,因此必须要专门的寄存器指向数据段(Data Segment),这就是DS寄存器的作用,DS是Data Segment的缩写。
  • 程序运行起来后还有运行时栈(Stack Segment),因此可以使用SS寄存器来指向程序员运行时栈,SS是Stack Segment的缩写。
  • 此外还有ES寄存器,Extra Segment,其用作临时段寄存器。

除了内存分段管理之外, 我们的程序可以读写任意内存区域 ,有的同学可能不以为意,这又能怎样呢?

没有内存保护会怎样?

至今,在多线程编程中这个问题依然困扰着程序员,因为同一个进程中的线程共享同一个地址空间,这也就意味着你的线程可以修改地址空间中任何可写的区域,包括栈区以及堆区,当然这也就意味着其它线程可以修改你的线程使用的数据,这是多线程中一大类bug的来源,关于这一部分的内容你可以参考《线程间到底共享了哪些进程资源?》。

而这个问题在内存地址没有任何保护情况下更加严重,因为这时不是一个进程而是多有进程包括操作系统都共享同一个物理内存地址,任何一个进程都可以修改内存中任何位置,你的进程可以破坏其他进程使用的内存,可以破坏操作系统使用的内存,破坏其它进程大不了重新启动这个进程,但是如果破坏了操作系统那么没有办法,此时你只能重新启动计算机,如果CPU没有提供内存保护机制,那么操作系统连自己都保护不了更何况去保护其它进程。

没想到吧,看似简单直接的内存读写竟然会有这么多问题。

实模式

好啦,到目前为止让我们暂且总结一下。

  • 绝对的内存地址不好用,这样的地址必须将程序加载到内存的特定位置上,为解决这个问题使用相对地址,x86中为每个程序的区域都配备有专用的寄存器用来存放该段在内存中的起始地址,这样就可以根据基址加偏移计算出物理内存地址,注意,这里计算出来的是真实的物理内存地址。
  • 内存读写没有任何保护,程序可以读写内存的任何区域。

实际上这就是早前内存管理的模式,非常直接非常原始,x86 CPU将这种原始的内存管理方法称之为实模式,real mode,这种模式也被称之为 real address mode ,顾名思义,我们在程序中看到的都是真实的物理内存地址。

图片

原来,早期的x86 CPU能访问的最大内存被限制在1MB(2^20 byte),你可能会想这可用内存也太少了吧,对于当今程序员或者用户来说1MB几乎什么都干不了,哪怕都存不下一首歌,然而在上世纪80年代,1MB内存是一片极为广阔的空间,以至于比尔盖茨在上世纪80年代说过:640k ought to be enough for anyone,对大部分人来说640K内存已经足够用了。

图片

除此之外,更加捉襟见肘的是早期x86 CPU寄存器只有16位,16位寄存器是没有办法访问整个1MB内存的,16位寄存器最多能访问64K大小的内存,要想访问1MB内存那么内存地址就需要20位,而寄存器本身就16位,因此根本装不下,怎么办呢?

很简单,一个寄存器不够我们就用两个,第一个寄存器被叫做selector,说白了其实存放的是储物柜区域的编号,因此也叫做段寄存器, segment register,管叫做区域还是叫做段本质上没啥区别。

第二个寄存器被叫做offset,说白了就是区域内的编号或者叫做区域内的偏移,这样真正的内存地址就由两部分组成 selector:offset ,此时内存地址的计算方式是这样的:

16 ∗ selector + offset

此时给定一个段寄存器再给出一个偏移我们就能直接在内存中找到需要的数据:

图片

因此这里计算出来的内存地址就是物理内存地址。

此外,在实模式下CPU不提供内存保护机制,程序可以随意读写任何内存区域,哪怕是操作系统所在的区域其它程序也可以读写。

现在可以总结下早期x86处理器的特点了:

  • 寻址空间有限,只有1MB
  • 利用 selector:offset的方式利用两个16位寄存器来寻址1MB内存
  • 没有内存保护机制,当然,没有内存保护机制的一大优点就在于内存读写速度要更快,原因就在于不需要经过虚拟内存地址到物理内存地址的转换,也不需要进行任何检查(这可能是实模式下仅有的优点)

在80286之前,所有x86 CPU都运行在实模式下,而为了后向兼容,即使是现代x86在重置(加电时)后也会首先进入实模式,后续才会跳转到保护模式(protected mode),关于保护模式我们在后续文章中讲解。

实模式与操作系统

实模式是x86系列处理器最早期的内存管理模式,这一时期的操作系统别无选择,只能运行在这种模式下,早期的DOS系统以及早期的Microsoft Windows操作系统就运行在实模式下。

虽然实模式理解起来很简单,但这种模式最主要的问题在于:

  1. 把物理内存暴露给程序
  2. 没有内存保护机制

这两者结合起来的后果就是 程序不被受限 ,程序员都知道,我们写的代码充满了bug,在现代操作系统中程序很容易把自己搞挂,而在早期的操作系统中程序就会很容易的把整个系统搞挂,为解决这一问题,x86 CPU在80286开始引入保护模式,后续文章会有详细讲解。

尽管现代操作系统(Windows、Linux)等早已不运行在实模式下,然而实模式却依然保留了下来,你可能会想为什么x86 CPU依然需要保留实模式呢?

我们都知道代码有屎山一说,其实对于历史悠久的x86来说也有类似的问题。

CPU这种硬件和软件一样也是在不断演变进化的,从16位实模式演进到了32位保护模式以及现代的64位处理器,但早期程序员围绕着16位实模式的x86CPU编写了很多软件,当CPU发展到32位保护模式时之前的基于16位实模式编写的软件该怎么办?不支持了吗?不支持的话只有两种可能:1) 用户不再购买不兼容16位软件的CPU 2) 重写代码,以程序员的尿性来说大概率不会重写,intel也非常识时务,因此在后来的32位乃至现代的64位处理器上依然保留了实模式,x86系列处理器在重置时会首先进入实模式,对于不使用实模式的现代操作系统来说简单的初始化工作后会跳转到保护模式。

因此我们可以看到,实模式就像原始的进化基因一样依然存在,就像动物胚胎有腮一样,只不过该过程一闪而过,实模式也是在计算机启动阶段快速闪现,这种古老的内存管理方式依然留下了自己的烙印。

图片

总结

实模式是一种非常古老的内存管理方式,在这种方法下程序员直面物理内存,且处理器没有提供内存读写机制,程序员可读写任何内存区域。

实际上实模式对于现代操作系统来几乎没什么用处,只不过如果你针对x86 CPU编写操作系统那么实模式是必须要了解的,但对于其它CPU来说则没有这样的历史包袱,因此有很多操作系统教材开始基于非X86平台来讲解,这样能更快速的讲解操作系统而不是在一上来就在各种内存模式中打转。

注意,本文提到的实模式仅仅针对x86系列处理器而言,对于上层应用的大部分程序员来说根本就不需要关心实模式,然而技术就和生物一样也在不断演变进化,了解过去才能更好的理解当下以及未来。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10843

    浏览量

    211416
  • 内存
    +关注

    关注

    8

    文章

    3009

    浏览量

    73957
  • 操作系统
    +关注

    关注

    37

    文章

    6771

    浏览量

    123254
收藏 人收藏

    评论

    相关推荐

    什么是操作系统

    什么是操作系统  操作系统是一个大型的软件系统,其功能复杂,体系庞大。从不同的角度看的结果也不同,正是“横看成岭侧成峰”,下面我们通过最典型的两个角度来分析一。  1.从程序员的角度
    发表于 09-13 10:10

    适合AMP同构非对称模式操作系统

    请问哪位知道代码开源的适合AMP,非对称模式操作系统,只需要简单的核间任务通信和资源同步就可以。
    发表于 12-11 17:38

    【安富莱】【RTX操作系统教程】第21章 RTX低功耗睡眠模式

    大家讲解STM32F103和STM32F407的低功耗方式睡眠模式在RTX操作系统上面的实现方法(RTX本身支持的tickless低功耗模式在第24章节讲解) 本章教程配套的例子含C
    发表于 02-04 16:39

    ARM CPU操作系统

    嵌入式操作系统是 ARM CPU的软件基础 从8 位/16位单片机发展到以ARM CPU核为代表的32位嵌入式处理器,嵌入式操作系统将替代传统的由手工编制的监控程序或调度程序,成为重要
    发表于 07-04 07:03

    HarmonyOS鸿蒙操作系统什么是“基于微内核的全场景分布式操作系统”?

    HarmonyOS鸿蒙操作系统什么是“基于微内核的全场景分布式操作系统”?即使作为理工科的人咋一眼看上去似乎也不太懂这是什么,就像区块链这个概念刚出来一样,普通人都是一脸懵B(当然现在我对这个也是
    发表于 09-23 17:06

    如何选择ARM CPU操作系统

    ARM CPU上广泛采用的嵌入式操作系统有哪几种?使用嵌入式Linux系统有哪几种途径?如何选择ARM CPU操作系统
    发表于 04-26 06:39

    MOS微型操作系统的设计与实现

    本文介绍一个基于Intel 80x86 CPU模式的多任务微型操作系统MOS的设计与实现。 着重阐述了MOS的层次结构、内存布局、引导
    发表于 07-30 10:19 10次下载

    什么是VxWorks操作系统

    VxWorksVxWorks操作系统是美国WindRiver公司于1983年设计开发的一种实时操作系统。VxWorks拥有良好的持续发展能力、高性能的内核以及良好的用户开发环境,在
    发表于 06-17 00:33 4077次阅读

    32位cpu、程序、操作系统是什么意思

    32位cpu、程序、操作系统指的是什么 1。32位指CPU的处理能力(如ALU、寄存器的位数)。     若数据总线也是32位,就是32位机,若数据总线只有16位,则是准32
    发表于 06-17 07:48 1819次阅读

    Linux操作系统训项目_虚拟机设置基础_RHEL_5.0_2

    嵌入式Linux操作系统训项目,虚拟机设置基础RHEL_5.0
    发表于 11-04 15:17 0次下载

    Data_ONTAP_集群模式操作系统

    Data_ONTAP_集群模式操作系统
    发表于 12-29 12:01 0次下载

    windows10操作系统安全模式的使用技巧

    谈到系统的安全模式大家并不陌生,在安全模式可以解决相关的电脑问题。windows操作系统的安全模式
    发表于 06-12 17:25 1145次阅读

    CPU的工作模式

    真实的指令,对指令的动作不作区分,直接执行指令的真实功能,另一方面是发往内存的地址是真实的,对任何地址不加限制地发往内存。1.2模式寄存器x86 CPU
    发表于 11-30 16:21 9次下载
    <b class='flag-5'>CPU</b>的工作<b class='flag-5'>模式</b>

    如何使服务器CPU在超频模式运行

    服务器已安装Windows Server操作系统,通过配置BIOS和电源选项可使CPU在超频模式运行。
    的头像 发表于 03-27 10:52 2605次阅读

    国产CPU操作系统被纳入政府采购清单:加速换国产OS

    国家发文要求将国产CPU操作系统纳入采购清单,涉及35个项目,将推动国产CPU操作系统产业发展。此举将提高我国信息系统安全性和可靠性,减
    的头像 发表于 05-13 17:42 1942次阅读
    国产<b class='flag-5'>CPU</b>和<b class='flag-5'>操作系统</b>被纳入政府采购清单:加速换国产OS