首页 > 其他分享 >存储管理方式

存储管理方式

时间:2023-10-14 16:33:07浏览次数:33  
标签:存储管理 保护模式 GDT 方式 16 地址 描述符 寄存器

分段式内存管理

  1. 原有的 16 位作系统是通过分段式内存管理,在只有四个段寄存器的情况下,每个寄存器里面所存的是基地址。

  1. 32 位操作系统发生了改变:

    1. 变化一:

    在 32 位时代,段寄存器又增加了两个:fs、gs,用来指向这两个表,分别是gdtr和ldtr,即全局描述符表GDT,也有可能是局部描述符表LDT。

    1. 变化 2:

    段寄存器里面存放的不再是段基地址,而是一个叫段选择子的东西。

  2. 段选择子:

    1. 在保护模式下时,由于段基址已经存入了段描述符中,所以段寄存器中再存放段基址是没有意义的,在段寄 存器中存入的是一个叫作选择子的东西。选择子“基本上”是个索引值,虽然它还有其他内容,不过作为初学者暂时忽略也没太大关系。由于段寄存器是 16 位,所以选择子也是 16 位,在其低 2 位即第 0~1 位, 用来存储 RPL,即请求特权级(有兴趣的可以了解一下,不想了解的忽略即可,跟用户态和内核态相关的),可以表示 0、 1、 2、 3 四种特权级。在选择子的第 2 位是 TI 位,即 Table Indicator,用来指示选择子是在 GDT 中,还是 LDT 中索引描述符。 TI 为 0 表示在 GDT 中索引描述符, TI 为 1 表示在 LDT 中索引描述符。选择子的高 13 位,即第 3~15 位是 描述符的索引值,用此值在 GDT 中索引描述符。前面说过 GDT 相当于一个描述符数组,所以此选择子中的索引值就是 GDT 中的下标。
  3. x86 寻址逻辑:

    1. 通过指示位找到是全局描述符表还是局部描述符表
    2. 在描述符当中找到段基地址
    3. 根据段基地址和偏移地址找到最后的逻辑地址

  1. 全局描述符 GDT 介绍:

    1. GDT全称Global Descriptor Table,是x86保护模式下的一个重要数据结构,在保护模式下,GDT在内存中有且只有一个。GDT的数据结构是一个描述符数组,每个描述符8个字节,可以存放在内存当中任意位置。

    2. 一个GDT段描述符占用8个字节,包含三个部分:

      1. 段基址(32位),占据描述符的第16~39位和第55位~63位,前者存储低16位,后者存储高16位。
      2. 段界限(20位),占据描述符的第0~15位和第48~51位,前者存储低16位,后者存储高4位。
      3. 段属性(12位),占据描述符的第39~47位和第49~55位,段属性可以细分为8种:TYPE属性、S属性、DPL属性、P属性、AVL属性、L属性、D/B属性和G属性。
  2. 实模式和保护模式:

    1. 实模式和保护模式都是 CPU 的工作模式,而 CPU 的工作模式是指 CPU 的寻址方式、寄存器大小等用来反应 CPU 在该环境下如何工作的概念。

      1. 实模式工作原理

        实模式出现于早期 8088CPU 时期。当时由于 CPU 的性能有限,一共只有 20 位地址线(所以地址空间只有 1MB),以及 8 个 16 位的通用寄存器,以及 4 个 16 位的段寄存器。所以为了能够通过这些 16 位的寄存器去构成 20 位的主存地址,必须采取一种特殊的方式。当某个指令想要访问某个内存地址时,它通常需要用下面的这种格式来表示:

        (段基址:段偏移量)

        其中第一个字段是段基址,它的值是由段寄存器提供的(一般来说,段寄存器有 6 种,分别为 cs,ds,ss,es,fs,gs,这几种段寄存器都有自己的特殊意义,这里不做介绍)。

        第二字段是段内偏移量,代表你要访问的这个内存地址距离这个段基址的偏移。它的值就是由通用寄存器来提供的,所以也是 16 位。那么两个 16 位的值如何组合成一个 20 位的地址呢?CPU 采用的方式是把段寄存器所提供的段基址先向左移 4 位。这样就变成了一个 20 位的值,然后再与段偏移量相加。

        即:

          物理地址 = 段基址 <<4 + 段内偏移
        DS * 16 + SI

        所以假设段寄存器中的值是 0xff00,段偏移量为 0x0110。则这个地址对应的真实物理地址是 0xff00<<4 + 0x0110 = 0xff110。

        由上面的介绍可见,实模式的"实"更多地体现在其地址是真实的物理地址。

    2. 保护模式:

      1. 偏移值和实模式下是一样的,就是变成了 32 位而已,而段值仍旧是存放在原来 16 位的段寄存器中,但是这些段寄存器存放的却不再是段基址了,毕竟之前说过实模式下寻址方式不安全,我们在保护模式下需要加一些限制,而这些限制可不是一个寄存器能够容纳的,于是我们把这些关于内存段的限制信息放在一个叫做全局描述符表(GDT)的结构里。全局描述符表中含有一个个表项,每一个表项称为段描述符。而段寄存器在保护模式下存放的便是相当于一个数组索引的东西,通过这个索引,可以找到对应的表项。段描述符存放了段基址、段界限、内存段类型属性(比如是数据段还是代码段,注意一个段描述符只能用来定义一个内存段)等许多属性。

分页式内存管理:

  1. 操作系统将内存空间按照“页”为单位划分了很多页面,这个页的大小默认是4KB(当然可以改的),各进程拥有虚拟的完整的地址空间,进程中使用到的页面会映射到真实的物理内存上,程序中使用的地址是虚拟地址,CPU在运行时自动将其翻译成真实的物理地址

  2. 页表是用来记录虚拟内存页面和物理内存页面之间的映射关系的,每一个页表项记录一个页面的映射关系。但进程的地址空间很大,这样算下来需要的页表项的数量也会非常多。而实际上进程地址空间中很多页面都没有真正使用,也就没有映射关系,这样是一种浪费。

    为了解决这个问题,CPU引入了多级页表的机制,在32位下一般是2级页表,像下面这样:

    将虚拟地址划分了三段:页目录索引、页表索引、页内偏移。

    线程切换时,如果同时发生了进程切换,CPU中的CR3寄存器将会加载当前进程的页目录地址。

    在寻址的时候,通过CR3,一级一级按表索页,最终找到对应的物理内存页面,再结合页面内的偏移值,实现最终的内存寻址。

参考文章:

  1. CPU 的实模式和保护模式 - 别再闹了 - 博客园 (cnblogs.com)
  2. x86 保护模式——全局描述符表 GDT 详解_gdt 字符-CSDN 博客
  3. 现代操作系统管理内存,到底是分段还是分页,段寄存器还有用吗? - 轩辕之风 - 博客园 (cnblogs.com)

标签:存储管理,保护模式,GDT,方式,16,地址,描述符,寄存器
From: https://www.cnblogs.com/ONEZJ/p/17764332.html

相关文章

  • python多线程with方式加锁
    python多线程with方式加锁"""pythonTreading中的Lock模块提供了加锁和释放锁的方法,分别是acquire()和release().这两个方法可以搭配python的with语句使用."""#示例fromthreadingimportLock​temp_lock=Lock()​withtemp_lock: print(temp_lock) #输出是<locked......
  • 使用Stream流将List转化为Map的几种方式
    在工作中常常会遇到将List转化为Map的场景,下面总结了经常使用到的几种方式;并简单的做了简单测试,供大家学习使用。准备工作:List<UserEntity>entityList=newArrayList<>();UserEntityuserEntity=newUserEntity();userEntity.setUserId("0001");userEntity.setUserName("00......
  • 文件默认打开方式 + mysql导入错误 + 输入法问题
    文件默认打开方式默认应用修改:设置—》应用—》默认应用—》按文件类型指定默认应用mysql导入错误Unknowncollation:'utf8mb4_0900_ai_ci'Mysql导入sql文件时,出Unknowncollation:'utf8mb4_0900_ai_ci'错误。原因:sql文件是从高版本mysql(8.0)中导出的,导入到......
  • Python JSON 库对 UTF8 字符的处理方式分析
    默认情况在使用json模块的json.dump时,默认会将非ASCII字符(中文字符等)进行Unicode转义,保证最终文件只有ASCII字符。例如下述代码:importjsonwithopen("text.json","w")asf:data={'1':111,'2':"你好",'3':"Hello",�......
  • 标准工时制度通过多种方式提高生产效率
    标准工时制度在现代企业管理中扮演着重要的角色,它可以通过多种方式提高生产效率。在如今竞争激烈的市场环境下,企业需要持续提高运营效率以保持竞争力。以下是标准工时制度提高生产效率的一些主要途径:首先,标准工时制度可以帮助企业更准确地预测生产需求。通过对历史数据和市场趋势......
  • 关于response.setHeader的重定向及多种界面跳转方式
    通过response.setHeader("refresh","1;URL=ttt.jsp");可以在一秒之后自动跳转到ttt.jsp界面 response.sendRedirect("ttt.jsp");立即跳转 <inputtype="button"onclick="javascript:window.location.href='ttt.jsp';&quo......
  • 使用Shell为UOS中的所有用户创建网页的快捷方式
    本脚本通过域管下发默认为root权限执行 #!/bin/bashcd/home#快捷方式图标名称string_imgName="temp1.png"#快捷方式文件名称string_fileName="/changePassword.desktop"#快捷方式内容functioninsertInfo(){cat>>$1$string_fileName<<EOF[DesktopEntry]#......
  • 你不知道的CANVAS 性能优化几种方式
    你不知道的CANVAS性能优化几种方式阿飞​红星美凯龙3D前端开发工程师​关注他 66人赞同了该文章背景什么是CANVAS?首先介绍下canvas,前端的同学可能很熟悉,举个很简单的例子,平常用的网页截图、H5游戏、前端动效、可视化图表...,都有canvas的......
  • 导热系数与传热系数有区别吗?二者的换算方式是怎样的?
    导热结构胶导热系数相信很多从事导热材料行业和使用导热材料的客户都不陌生,也能够说出个一二三,但传热系数可能大家就不那么熟悉了,所以,今天GLPOLY导热材料小编就简单给大家普及一下导热系数与传热系数有区别吗?二者的换算方法是怎么的?传热系数与导热系数定义差别导热系数一般是针......
  • 开源项目 | SpringBoot+XXL-JOB 构建的汽车之家开源的监控平台,支持多种报警消息发送方
     一、项目概述Frostmourne(霜之哀伤)是汽车之家经销商技术部监控系统的开源版本,用于帮助监控几乎所有数据库数据(包括Elasticsearch,Prometheus,SkyWalking,MySql等等)。如果你已经建立起了日志系统,指标体系,却苦恼于没有一个配套监控系统,也许它能帮到你。使用本系统得当,至......