做i爱小说网站/广州网络推广哪家好
前言:
操作系统的特权级模块在整个操作系统的学习中应该算的上是最难啃的了,提到特权级就要绕不开保护模式下的分段机制;如果想要彻底弄明白就要对比实模式下的分段机制有什么缺陷。这就衍生出很多问题如:什么是实模式?采用分段机制进行寻址的意义?什么是保护模式?为什么要设计保护模式?…?
如果只是针对性的单独回答某个问题一直在罗列八股文要点,只讲“是什么”而忽略“为什么”,初学者看完之后会感觉始终没学透彻,更适合与有基础的人复习。任何事物发展到今天,都有段“合理”的过程,了解这个过程是怎么来的,有助于理解它今天的形态。在“处理器的发展史”中分段机制、保护模式等每一个机制的出现都是为了解决当时的一个重大问题,要想彻底把特权级模块啃透,就必不可免要去了解一下“处理器的发展史”(之所以是“处理器的发展史”而不是“操作系统的发展史”,是因为分段机制、保护模式、特权级这些概念都是处理器的工程师们设计的,操作系统只是一个协助者和应用者,后面会解释)。很多文章在梳理“处理器的发展史”的过程中无法抓住重点,花费大量篇幅讲解不关键的点,让人读起来容易分散精力,甚至读完以后忘记为啥点进来了。比如:为什么要采用分段机制进行寻址?“从分段机制首次出现的8086 处理器开始讲起,花费大量篇幅介绍8086 处理器是如何利用分段机制 在16位寄存器的基础上使用20位地址总线进行寻址的。” 却忽略了分段机制引入的关键是为了解决程序动态重定向问题,或者一笔带过。在计算机的发展史中每一种新机制的引入都是为了解决一个或多个痛点,我们要抓住最痛的那个点,因为不到万不得已是不会引入新机制的,充分利用20位地址总线的问题显然增加寄存器的容量为20位来的更简单,并不是引入分段机制的核心原因。文章开始前给大家推荐三本书:操作系统真相还原(强烈推荐)、30天自制操作系统、深入理解Linux内核
接下来我们就沿着“处理器的发展史”来看下操作系统的特权级机制是如何发展的。首先我们挑选两个里程碑:1.分段机制首次出现;2.保护模式首次出现
在看 CPU 的实模式和保护模式的文章之前,建议大家先花费十几分钟时间,看下这几篇处理器相关文章:因为无论 CPU 在哪种模式下工作,核心工作原理是不变的,有了这一思想武装起来后再讲模式就简单多了。
CPU与指令集、自研指令集难吗?、CPU如何执行指令以及流水线技术
本篇主要是围绕第一个里程碑来讲解“实模式”下的分段机制。首选介绍一下什么是“实模式”,CPU 中本来是没有实模式这一称呼的,是因为有了保护模式后,为了与老的模式区别开来,所以称老的模式为实模式。就好比汽车中的自动挡和手动挡,本来是没有手动挡这个概念的,因为后来有了自动挡汽车,先前的汽车就被称为手动挡汽车了。
在“处理器的发展史” 分段机制首次出现在Intel的8086CPU中。不知道大家有没有这样的疑虑这都2023年了还用8086这样的古董CPU讲解知识是否太落伍了,学到的知识在现代CPU中能用得上嘛。这个请大家放心,Intel 8086 CPU 应该称为80x86,它是Intel x86指令集架构下的第一款CPU,其中的86代表的是x86指令集体系,自那以后的CPU称为 286 386 486 586……即使现在的”酷睿“、”奔腾“也都属于x86系列。所以道理是不变的,而且用最简单的 80x86 CPU 学习,更容易理解和看透 CPU 运行机制。
8086之所以称为CPU界的里程碑就是因为它引入了分段机制来进行内存访问。在它之前的CPU对内存的访问比8086还有“实诚”,它们没有段的概念,程序要计算机上运行必须采用静态重定位的方式将内存地址“硬编码“写死在代码中,这导致程序首次装入内存后程序在内存中的位置就不可移动了,操作系统无法再次对程序进行重定位操作。
什么是静态重定向?我们用高级语言编写的源代码想要机器上运行需经历 编辑、编译、链接、装入、运行五个阶段,要想在CPU上运行就要遵循CPU的规则,在8086之前的CPU没有”段“的概念,CPU直接以真实物理地址访问内存,没有任何花哨,要在CPU上运行的程序必须直接使用包含真实物理地址的指令。首先编译和链接阶段由于编译器和链接器不能确定程序装入内存后的真实物理地址,所以产生的机器指令都采用以“0x00000”作为参考地址的相对地址也称为逻辑地址,等待程序首次装入内存时操作系统的装入程序模块会对目标程序中的地址相关的机器指令进行修改,将逻辑地址转换为真实的物理地址,这个过程就是静态重定向。列入:程序装入前机器指令 mov eax,0x00100 ,代表将逻辑地址0x00100中的数据"666"装入寄存器eax,程序装入时操作系统分配了以0x0c000为起始位置的物理内存,此时"666"对应的真实物理地址为0x0c100,因此上述指令会被修改为 mov eax,0x0c100 ,这样程序就能准确无误的在CPU上运行了但此后程序内存中的位置就不可移动了,因为指令中的物理地址已经不会再被改变了,如果程序移动了就会出现不可知异常。
明白了静态重定向,我们来看下仅仅依靠静态重定向的程序在运行时有什么弊端。在静态重定向机制下程序首次装入内存后就不能再次在内存中移动了,在这个前提下再牛逼的操作系统也无法高效的完成内存的回收和分配。导致本就不富裕的内存空间还会产生大量的外部碎片,无法被充分利用。如下场景,有可用内存160KB,但由于程序A位置不可移动,程序B虽然仅需100KB内存却无法运行。
上述囧况让本不富裕的内存雪上加霜,Intel早期的工程师难以承受内心的自责,不顾自己满头白发,熬了无数个通宵后,终于发明了“段”,从此CPU访问内存采用“段+偏移”的形式,地址重定位由静态重定位变为动态重定位。
怎么理解动态重定位?动态重定位不需要在装入阶段进行指令的修改,而是在执行阶段每次CPU访问内存时进行逻辑地址到物理地址的转换,动态重定位不需要装入程序模块的软件支持,需要CPU的硬件支持。引入段基址寄存器,用于保存程序被分配的起始物理地址即段基地址,编译和链接后生成的逻辑地址即段内偏移地址。程序运行过程中CPU在访问内存时会将段基址寄存器中的段基地址与段内偏移地址相加得到真正的物理地址。
如上图程序在装入内存后地址相关的机器指令不会被修改,依旧使用编译链接后的逻辑地址,逻辑地址与物理地址的转换是在执行包含内存寻址相关指令时由硬件完成的。转换的方式就是取段基址寄存器中的段基地址与逻辑地址相加的结果进行寻址。如若操作系统想要移动程序在内存中的位置只要将段基址寄存器中的段基地址更新为新位置的起始物理地址即可。
在分段机制下程序可以在内存中随意移动,这给了操作系统在内存管理方面很大发挥空间。例如:上述内存充足,但碎片化导致程序B无法运行的囧况就可以通过内存压缩的方法将内存碎片合并。
处理器工程师还在分段机制的基础上将每个运行时程序所占内存分解成了:代码段+数据段+栈段+BSS段+堆段,将连续逻辑地址空间分散到多个非连续的物理内存空间中,这也是内存分配的一种优化,可以合理利用内存碎片如下图。
处理器工程师还为每个内存段设计了专门的段基址寄存器用来储存段基址如:cs、ds、ss、es、fs、gs。
- 代码段:代码段简而言之就是把所有指令都连续排放在一起,形成了一个全部都是指令的区域,里面储存的是指令的操作码及寻址方式等。该区域可以在硬盘上的文件中,也可以是被加载后的内存中,总之是一段指令区域。它们内部都是紧凑挨着的,内容形式完全一样,只是存放的介质不一样而已。CPU专门提供了CS段寄存器用来保存指向这个块区域的起始地址。CS寄存器中的起始地址加上IP寄存器中的段内偏移地址为CPU提供了导航功能。CPU执行到何处完全要听这两个寄存器的安排。
- 数据段:数据段和代码段类似,只是这段区域中的内容不是指令,而是存粹的数据,也就是说里面存储的是程序运行所需要的数据,属于指令中的操作数。CPU专门提供了DS段寄存器用来储存这段区域的起始地址。
- 栈段:栈段是在内存中,硬盘文件中没有,一般的栈段是由操作系统分配指定的,所以是程序被加载到内存后才有的,栈段算是一种特别的数据段,和普通数据段不同的是栈段起始地址是高地址,向低地址方向扩展。所以CPU专门提供了SS段寄存器用来储存这块区域的起始地址。
代码段(cs)、数据段(ds)、栈段(ss)寄存器从名字上就比较容易理解,那es、fs、gs这三个附加段寄存器是干吗的?其实就是多给大家提供几个段寄存器用而已,可以作为BSS段和堆段的段基址寄存器,多几个寄存器用不是更好嘛,省的紧紧巴巴的,纯粹是为了方便大家。
以上就是分段策略出现的原因,它就是首次在8086上出现,自那之后的CPU都是用这类思想访问内存,只是在形式上有小改动,所以8086如此极负盛名。随着技术的发展虽然后来设计出了分页机制,它可以更好的管理内存,提高内存的利用率和内存交互性能。但任何事物发展到今天,都有段“合理”的过程,虽然分段机制并不完美,但它依然是处理器发展史上的一个里程碑,由于x86架构的CPU都会向前兼容,所以分段机制时至今日依然被保留了下来,目前CPU大都采用分段+分页机制并存的段页式内存管理机制,CPU在进行内存寻址前先将逻辑地址通过分段机制转换成虚拟地址(线性地址),虚拟地址再经过分页机制转换成真实的物理地址,当然也可以和 Linux 操作系统那样让每一段的基地址都设为 0 ,这样就等于“绕开”了段机制。
相关文章:

特权级那些事儿-实模式下分段机制首次出现的原因
前言: 操作系统的特权级模块在整个操作系统的学习中应该算的上是最难啃的了,提到特权级就要绕不开保护模式下的分段机制;如果想要彻底弄明白就要对比实模式下的分段机制有什么缺陷。这就衍生出很多问题如:什么是实模式?…...

详解Vue安装与配置(2023)
文章目录一、官网下载node.js二、安装Node.js三、环境配置四、idea导入vue项目五、IDEA添加Vue.js插件一、官网下载node.js Vue是前端开发框架。搭建框架,首先要搭建环境。搭建Vue的环境工具:node.js(JavaScript的运行环境)&…...

TypeScript深度剖析:Vue项目中应用TypeScript?
一、前言 与link类似 在VUE项目中应用typescript,我们需要引入一个库vue-property-decorator, 其是基于vue-class-component库而来,这个库vue官方推出的一个支持使用class方式来开发vue单文件组件的库 主要的功能如下: metho…...

linux面试高级篇
题目目录1.虚拟机常用有几种网络模式?请简述其工作原理或你个人的理解?2. Dockerfile中最常见的指令是什么?3.docker网络模式有哪些?4.Kubernetes有哪些核心组件这些组件负责什么工作?5. Pod是什么?6.描述一…...

java 4 (面向对象上)
java——面向对象(上) 目录java——面向对象(上)面向对象的思想概述类的成员(1-2):属性和方法对象的内存解析类中属性的使用类中方法的使用1.举例:2.声明方法:3.说明4.re…...

HTTP报头的2个方法
在采集网页信息的时候,经常需要伪造报头来实现采集脚本的有效执行 下面,我们将使用urllib2的header部分伪造报头来实现采集信息 方法1、 #!/usr/bin/python -- coding: utf-8 -- #encodingutf-8 #Filename:urllib2-header.py import urllib2 import…...

yolov5双目检测车辆识别(2023年+单目+双目+python源码+毕业设计)
行人识别yolov5和v7对比yolo车距源码:yolov5双目检测车辆识别(2023年单目双目python源码毕业设计)上盒岛APP,开线上盲盒商店http://www.hedaoapp.com/yunPC/goodsDetails?pid4132 为了提高传统遗传算法(genetic algorithm, GA)IGA优化BP网络迭代时间过长以及精度偏…...

华为OD机试题,用 Java 解【用户调度问题】问题
华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典使用说明 参加华为od机试,一定要注意不…...

根据mybatis plus注解动态创建sqlite表和表字段
根据mybatis plus注解动态创建sqlite表和表字段 启动时动态创建sqlite数据库,根据mybatis plus注解动态创建表。如果有新增字段,动态创建字段。 文章目录根据mybatis plus注解动态创建sqlite表和表字段一、初始化数据库1.系统启动时初始化数据库2.初始化…...

同步、异步ETL架构的比较
背景介绍: 数据的抽取,转换和加载 (ETL, Extract, Transform, Load) 是构建数据仓库过程中最复杂也是至 关重要的一个步骤,我们通常用两种办法来处理 ETL 流程: 一种是异步(Asynchronous) ETL 方式, 也称为文本文件(Flat file)方式。 另外…...

【机会约束、鲁棒优化】具有排放感知型经济调度中机会约束和鲁棒优化研究【IEEE6节点、IEEE118节点算例】(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

用Python帮老叔选出好基金,大赚一笔,老叔专门提着茅台登门道谢
我有个老叔很喜欢买基金,因为不想被割韭菜,所以啥群都没进,全部自己精挑细选。 看着他的一个本子密密麻麻地写了一大堆东西,全是基金的数据分析,一大把年纪了挺不容易的,于是就决定帮他一把。 在跟他详谈…...

ZeroTier实现内网穿透详细教程,无需公网IP,实现异地组网
ZeroTier实现内网穿透详细教程,无需公网IP,实现异地组网ZeroTier1.官网注册账号,创建自己的局域网段2.点击创建好的网络,进入设置界面进行设置3.下载客户端,安装客户端,然后连接到网络中4.加入网络成功后&a…...

电商 SaaS 全渠道实时数据中台最佳实践
摘要:本文整理自聚水潭数据专家张成玉,聚水潭高级数据工程师应圣楚,在 FFA 2022 行业案例专场的分享。本篇内容主要分为四个部分:实时数仓的建设和发展数据中台的产品体系及架构实时计算的实践和优化对实时计算的未来展望Tips&…...

macos ncnn 安装踩坑记录···
安装真麻烦踩了无数坑,官方给的安装教程:macos安装ncnn, 安装过程老是报错,记录一下卡的比较久的,网上也不好找资料的错. 我的电脑: 1. 使用homebrew 的时候失败fatal: not in a git directory Error: Command failed…...

ESP32设备驱动-AM2301(DHT21)温度湿度传感器驱动
AM2301(DHT21)温度湿度传感器驱动 文章目录 AM2301(DHT21)温度湿度传感器驱动1、AM2301(DHT21)介绍2、硬件准备3、软件准备4、驱动实现1、AM2301(DHT21)介绍 AM2301 湿敏电容数字温湿度模块是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温…...

[数据结构]:16-归并排序(顺序表指针实现形式)(C语言实现)
目录 前言 已完成内容 归并排序实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-PSeqListFunction.cpp 04-SortFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容,除其中使用到C引用外,全为C语言代码。使用C引用主要是…...

React(七):Router基本使用、嵌套路由、编程式导航、路由传参、懒加载
React(七)一、React-Router的基本使用1.安装和介绍2.路由的配置和跳转3.Navigate的使用4.如果找不到对应的路由路径?二、嵌套路由的用法三、编程式路由导航1.类组件中使用useNavigate2.函数式组件中使用useNavigate四、路由跳转传参1.设置好路…...

Java基础面试题(一)
Java基础面试题 一、面向对象和集合专题 1. 面向对象和面向过程的区别 面向过程:是分析解决问题的步骤,然后用函数把这些步骤一步一步地实现,然后在使用的时候一一调用则可。性能较高,所以单片机、嵌入式开发等一般采用面向过程…...

代码命名规范是一种责任也是一种精神(工匠精神)
代码命名规范之美规范概述命名规范管理类命名BootstrapProcessorManagerHolderFactoryProviderRegistrarEngineServiceTask传播类命名ContextPropagator回调类命名Handler ,Callback,Trigger,ListenerAware监控类命名MetricsEstimatorAccumul…...

奇淫技巧:阅读源码时基于一组快捷键,让我们知道身在何方!
一个十分蛋疼的问题 在我们阅读框架底层源码的时候,我们往往会一个方法一个方法的往下翻,翻了很久很快就会有这样的灵魂拷问:我从那个类(方法)来,我要到哪个(类)方法中去。这个时候…...

你真的弄懂this指向了吗
前言 在说 this 指向之前,请观察以下代码,并说出它们的输出结果: 第 1 组:标准函数 window.color "red"; let o {color: "blue", }; function sayColor() {console.log(this.color); }sayColor(); // 输…...

阿里云服务器使用教程:使用xshell、xFtp工具连接阿里云服务器(Centos7)并修改Centos7的yum源为阿里镜像源
目录 1、下载并安装xshell、xFtp 2、远程连接阿里云服务器 3、 修改Centos7的yum源为阿里镜像源 1、下载并安装xshell、xFtp XShell可以在Windows界面下来访问远端不同系统下的服务器,从而比较好的达到远程控制终端的目的。它支持 RLOGIN、SFTP、SERIAL、TELNET、…...

一文快速入门 HTML 网页基础
专栏简介: 前端从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录 1.HTML 结构 1.1. 认识 HTML 标签 1.2 HTML 文件结构…...

DEJA_VU3D - Cesium功能集 之 100-任意多边形(标绘)
前言 编写这个专栏主要目的是对工作之中基于Cesium实现过的功能进行整合,有自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小140个左右的功能,后续也会不断的追加,所以暂时打算一周2-3更的样子来更新本专栏(每篇博文都会奉上完整demo的源代码,…...

Cadence OrCAD Capture全局修改原理图的非本地库符号的方法图文教程Repalce Catch功能
⏪《上一篇》 🏡《总目录》 ⏩《下一篇》 目录 1,概述2,修改方法2.1,新建本地库2.2,待修改搬入本地库2.3,修改原理图符号2.4,全局更新原理图符号3,总结B站关注“硬小二”浏览更多演示视频 1,概述 在完成原理图设计...

npm包版本号详解
npm包在发布时,需要按照包版本语义化中的约定去更新设置,例如我们常见的1.0.0,1.0.1,0.0.1等这样的版本号,那么这些数字分别代表什么意思呢?下面我们将详细介绍。 npm版本号的组成 一个完整的版本号&…...

ubuntu 系统安装docker——使用docker打包python项目,整个流程介绍
目录 1 安装docker和配置镜像源 2 下载基础镜像 3 通过镜像创建容器 4 制作项目所需的容器 5 容器制作好后打包为镜像 6 镜像备份为.tar文件 7 从其他服务器上恢复镜像 8 docker的其他常用指令 首先科普一下镜像、容器和实例; 镜像:相当于安装包&…...

MySQL事务篇
MySQL事务篇 一、一条Insert语句 为了故事的顺利发展,我们需要创建一个表: CREATE TABLE t (id INT PRIMARY KEY,c VARCHAR(100) ) EngineInnoDB CHARSETutf8;然后向这个表里插入一条数据: INSERT INTO t VALUES(1, 刘备); 现在表里的数据就…...

【Redis】搭建分片集群
目录 集群结构 准备实例和配置 启动 创建集群 测试 集群结构 分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个 master包含一个slave节点,结构如下: 这里我们会在同一台虚…...