CPU工作模式- 保护模式

news2024/9/20 10:59:25

保护模式

概述

  • 随着软件的规模不断增加,需要更高的计算量、更大的内存容量
  • 内存一大,首先要解决的问题是寻址问题,因为16位的寄存器最好只能表示 2 16 2^{16} 216个地址,所以CPU的寄存器和运算单元都要扩展成32位
  • 虽然扩展CPU内部器件的位数解决了计算和寻址问题,但仍然没有解决前面那个实模式场景下的问题,导致前面的场景出现的问题的原因
    • CPU对任何指令不加区分地执行
    • CPU对访问内存的地址不加限制

保护模式寄存器

寄存器描述
EAX、EBX、ECX、EDX、EDI、ESI、EBP32位通用寄存器,里面可以存放数据、地址、参与运算
EIP32位程序指针寄存器,始终指向下一条指令的地址
ESP栈指针寄存器,始终指向当前栈顶
CS、DS、ES、SS、FS、GS16位段寄存器,里面存放一个内存段的描述符索引
EFLAGS32位CPU标志寄存器,里面存放CPU执行指令产生的状态位
CR0、CR1、CR2、CR332位CPU控制器,控制CPU的功能控制特性,如开启保护模式等
  • 保护模式相比于实模式,增加了一些控制寄存器和段寄存器,扩展通用寄存器的位宽,所有的通用寄存器都是32位
  • 还可以单独使用低16位,这个低16位又可以拆分成两个8位寄存器

保护模式特权级

  • 为了区分哪些指令(如in、out、cli)和哪些资源(如寄存器/I/O端口、内存地址)可以被访问,CPU实现了特权级

  • 在这里插入图片描述

    • 特权分为4级,R0 ~ R3,每个特权级执行指令的数量不同,R0可以执行所有指令,R1、R2、R3依次递减,它们只能执行上一级指令数量的子集
    • 而内存的访问则是靠后面所说的段描述符和特权级相互配合去实现
  • 上面的圆环图,从外到内,既能体现权利的大小,又能体现各特权级对资源控制访问的多少,还能体现各特权级之间的包含关系

  • R0拥有最大权利,可以访问低特权级的资源,反之则不行

保护模式段描述符

  • 目前为止,内存还是分段模型,要对内存进行保护,就可以转换成对段的保护

  • 由于CPU的扩展导致了32位的段基地址和段内偏移,所以 16 位的段寄存器肯定放不下

  • 放不下就要找内存借空间,然后把描述一个段的信息封装成特定格式的段描述符,放在内存中

    • 在这里插入图片描述

    • 一个段描述符有64位8字节数据,里面包含了段基地址、段长度、段权限、段类型(可以是系统段、代码段、数据段)、段是否读写、可执行

  • 在这里插入图片描述

    • 多个段描述符在内存形成全局段描述符表,该表的基地址和长度由CPU和GDTR寄存器指示
    • 一眼看出,段寄存器中不再存放段基地址,而是具体段描述符的索引,访问一个内存地址时
    • 段寄存器中的索引首先会结合GDTR寄存器找到内存中的段描述符,再根据其中的段信息判断能不能访问成功

保护模式段选择子

  • 在这里插入图片描述

    • CS、DS、ES、SS、FS、GS这些段寄存器是由影子寄存器、段描述符索引、描述符表索引、权限级别组成
    • 影子寄存器是靠硬件来操作,对系统程序员不可见,是硬件为了减少性能损耗而设计的一个段描述符的高速缓存,不然每次内存访问都要要去内存中查表,那性能损失是巨大的,影子寄存器也正好是64位,里面存放了8字节段描述符数据
    • 低三位之所以能放TI和RPL,是因为段描述符8字节对齐,每个索引低3位都位0
      • 这部分的意思是指,因为段描述符8字节对齐,所以它的索引都是8的整数倍,因此低3位都为0
      • 类似1000,10000,11000这样的。所以低3位可以用来做其他事,这里就用来放TI和RPL
  • 通常情况下,CS和SS中RPL就组成了CPL(当前权限级别),所以常常是RPL=CRL

    • 进而 CPL 就表示发起访问者要以什么权限去访问目标段,当 CPL 大于目标段 DPL 时,则 CPU 禁止访问
    • 只有 CPL 小于等于目标段 DPL 时才能访问

保护模式平坦模型

  • 但是 x86 CPU 并不能直接使用分页模型,而是要在分段模型的前提下,根据需要决定是否要开启分页
  • 因为这是硬件的规定,程序员是无法改变的。但是我们可以简化设计,来使分段成为一种“虚设”,这就是保护模式的平坦模型
  • 发现 CPU 32 位的寄存器最多只能产生 4GB 大小的地址,而一个段长度也只能是 4GB
    • 所以我们把所有段的基地址设为 0,段的长度设为 0xFFFFF
    • 段长度的粒度设为 4KB,这样所有的段都指向同一个(0~4GB-1)字节大小的地址空间
  • 例子
GDT_START:
knull_dsc: dq 0
;第一个段描述符CPU硬件规定必须为0
kcode_dsc: dq 0x00cf9e000000ffff
;段基地址=0,段长度=0xfffff
;G=1,D/B=1,L=0,AVL=0 
;P=1,DPL=0,S=1
;T=1,C=1,R=1,A=0
kdata_dsc: dq 0x00cf92000000ffff
;段基地址=0,段长度=0xfffff
;G=1,D/B=1,L=0,AVL=0 
;P=1,DPL=0,S=1
;T=0,C=0,R=1,A=0
GDT_END:

GDT_PTR:
GDTLEN  dw GDT_END-GDT_START-1
GDTBASE  dd GDT_START
  • 段长度需要和 G 位配合,若 G 位为 1 则段长度等于 0xfffff 个 4KB
  • 上面段描述符的 DPL=0,这说明需要最高权限即 CPL=0 才能访问

保护模式中断

概述

  • 因为实模式下CPU不需要做权限检查,所以它可以直接中断向量表中的值装载CS:IP寄存器

中断门结构

  • 在这里插入图片描述

  • 而保护模式下的中断权限检查,还有特权级的切换,就需要扩展中断向量表的信息

  • 即每个中断用一个中断门描述符来表示,也可以简称中断门

中断流程图例

  • 在这里插入图片描述

  • 保护模式要实现中断,必须在内存中有一个中断向量表,同样由IDTR寄存器指向

  • 只不过中断向量表中的条目变成了中断门描述符

中断流程

  • 产生中断后,CPU首先会检查中断号是否大于最后一个中断门描述符, x86 CPU 最大支持256个中断源(即中断号: 0 ~ 255)
  • 然后检查描述符类型(是否是中断门或者陷阱门)、是否为系统描述符,是否存在于内存中
  • 接着,检查中断门描述符中的段选择子指向的段描述符
  • 权限检查
    • 如果CPL小于等于中断门的DPL并且CPL大于等于中断门中的段选择子,就指向段描述符的DPL
    • 进一步的,CPL等于中断门中的段选择子指向段描述符的DPL,则为同级权限不进行栈切换,否则进行栈切换
    • 如果进行栈切换,还需要从TSS中加载具体权限的SS、ESP、当然也要对SS中段选择子指向的段描述符进行检查
  • 做完这一系列检查之后,CPU才会加载中断门描述符中目标代码段选择子到CS寄存器中,把目标代码段偏移加载到EIP寄存器中

切换到保护模式

概述

  • x86 CPU在第一次加电和每次reset后,都会自动进入实模式,想要进入保护模式,就需要程序员写代码实现从实模式切换到保护模式

切换步骤

第一步,准备全局段描述符
GDT_START:
knull_dsc: dq 0
kcode_dsc: dq 0x00cf9e000000ffff
kdata_dsc: dq 0x00cf92000000ffff
GDT_END:
GDT_PTR:
GDTLEN  dw GDT_END-GDT_START-1
GDTBASE  dd GDT_START
第二步,加载设置GDTR寄存器,使之指向全局段描述符表
lgdt [GDT_PTR]
第三步,设置CR0寄存器,开启保护模式
;开启 PE
mov eax, cr0
bts eax, 0                      ; CR0.PE =1
mov cr0, eax         
第四步,进行长跳转,加载 CS 段寄存器,即段选择子
jmp dword 0x8 :_32bits_mode ;_32bits_mode为32位代码标号即段偏移
  • 为什么要进行长跳转,这是因为我们无法直接或间接 mov 一个数据到 CS 寄存器中
  • 因为刚刚开启保护模式时,CS 的影子寄存器还是实模式下的值,所以需要告诉 CPU 加载新的段信息
最后
  • 接下来,CPU 发现了 CRO 寄存器第 0 位的值是 1
  • 就会按 GDTR 的指示找到全局描述符表,然后根据索引值 8,把新的段描述符信息加载到 CS 影子寄存器,当然这里的前提是进行一系列合法的检查
  • CPU 真正进入了保护模式,CPU 也有了 32 位的处理能力

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1939378.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UDP详细总结

UDP协议特点 UDP是无连接的传输层协议; UDP使用尽最大努力交付,不保证可靠交付; UDP是面向报文的,对应用层交下来的报文,不合并,不拆分,保留原报文的边界; UDP没有拥塞控制&#…

ArrayList.subList的踩坑

需求描述&#xff1a;跳过list中的第一个元素&#xff0c;获取list中的其他元素 原始代码如下&#xff1a; List<FddxxEnterpriseVerify> companyList fddxxEnterpriseVerifyMapper.selectList(companyQueryWrapper);log.info("获取多个法大大公司数据量为&#…

【python 已解决】 ‘ValueError: invalid literal for int() with base 10’解决方案深度解析

【python 已解决】 ‘ValueError: invalid literal for int() with base 10’解决方案深度解析 在Python编程中&#xff0c;ValueError: invalid literal for int() with base 10是一个常见的错误&#xff0c;它通常表明在尝试将字符串转换为整数时&#xff0c;字符串中包含了无…

【开发踩坑】生僻字插入MySQL失败

背景 生产环境插入数据报错&#xff1a; java.sql.SQLException: Incorrect string value: \xF0\xAC\xB1\x96 for column answer at row 1设置answer字段值为 “&#x2cc56;”出现错误 生僻字设置出错&#xff1b; 排查 编码 查看库表属性&#xff1a; ENGINE InnoDB A…

【接口自动化_08课_Pytest+Yaml+Allure框架】

上节课一些内容 的补充 1、openxl这个方法&#xff0c;第一个元素是从1开始的&#xff0c;不是从0开始 回写的列在程序里写的是11&#xff0c;是因为是固定值 一、1. Yaml入门及应用 1、什么是yaml YAML&#xff08;/ˈjməl/&#xff0c;尾音类似camel骆驼&#xff09;是一…

springboot+vue+mybatis校园热点新闻系统+PPT+论文+讲解+售后

21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存储达到…

贪心算法(算法篇)

算法之贪心算法 贪心算法 概念&#xff1a; 贪心算法是一种思想&#xff0c;并不是一种算法&#xff0c;贪心算法是分阶段地工作&#xff0c;在每一个阶段&#xff0c;可以认为所作决定是好的&#xff0c;而不考虑将来地后果。算法的每个阶段总是选择当前阶段最优&#xff0…

ChatGPT成功背后的秘密——RLHF,北京大学NLP团队的论文详解来了

1、简介&#xff1a; 人工智能对齐(AIAlignment) 旨在使人工智能系统的行为与人类的意图和价值观相一致。随着人工智能系统的能力日益增强&#xff0c;对齐失败带来的风险也在不断增加。数百位人工智能专家和公众人物已经表达了对人工智能风险的担忧&#xff0c;他们认为“减轻…

【芯片设计- RTL 数字逻辑设计入门 番外篇 12 -- SoC 设计中的 ECO】

请阅读【ARM AMBA AXI 总线 文章专栏导读】 请阅读【芯片设计 RTL 数字逻辑设计扫盲 】 转自&#xff1a;简单了解SoC设计中的ECO — 快乐的芯片工程师 文章目录 ECO 概述Pre-Mask ECO&#xff08;预掩模ECO&#xff09;芯片设计前端与后端的区别 Post-Mask ECO&#xff08;后…

PyTorch Tabular:高效优化结构化数据处理的强大工具

PyTorch Tabular 是一个用于构建和训练深度学习模型以解决各种表格数据问题的库。这个库专为表格数据设计&#xff0c;通过提供灵活的、易于使用的API来简化模型的构建、训练和推理过程。PyTorch Tabular 基于 PyTorch&#xff0c;利用了 PyTorch 的动态计算图和强大的GPU加速能…

10款打工人必备工具网站,提升工作效率

工作效率对于每一位打工人来说都尤为重要&#xff0c;小编就来和大家分享优质的打工人必备工具网站&#xff0c;帮助大家提升工作效率。 1. 办公人导航 办公人导航是一个专门为办公人员设计的实用导航网站&#xff0c;旨在帮助用户高效地找到各种优质的办公资源和工具。该网站…

vscode配置django环境并创建django项目(全图文操作)

文章目录 创建项目工作路径下载python插件&#xff1a;创建虚拟环境1. 命令方式创建2. 图文方式创建 选择虚拟环境在虚拟环境中安装Django创建Django项目 创建项目工作路径 输入 code . 下载python插件&#xff1a; 创建虚拟环境 1. 命令方式创建 切换在工作目录输入命令&…

Linux工具相关介绍

目录 1.linux安装软件 2.Linux软件生态问题 3.linux软件包管理器yum 4.linux里面好玩的小命令 4.1安装源 4.2小火车 4.3人物说话情景 5.vim简单介绍 5.1简单认识 5.2代码编写 5.3命令模式 1.linux安装软件 1.1源代码安装&#xff1a;这个里面可能根据代码bug需要修改…

2024牛客暑期多校训练营1——A,B

题解&#xff1a; 更新&#xff1a; k1的时候要乘n 代码&#xff1a; #include<bits/stdc.h> #define int long long using namespace std; const int N5e35; typedef long long ll; typedef pair<int,int> PII; int T; int n,m,mod; int fac[N][N]; int dp[N][…

字符函数和字符串函数(一)

一、字符分类函数 C语言中有一系列的函数是专门做字符分类的&#xff0c;也就是一个字符是属于什么类型的字符。 这些函数的使用都需要包含一个头文件&#xff1a;ctype.h 这些函数的使用方法非常类似&#xff0c;在这里讲解islower&#xff1a; islower是能够判断参数部分的…

算法day05 master公式估算递归时间复杂度 归并排序 小和问题 堆排序

2.认识O(NlogN)的排序_哔哩哔哩_bilibili master公式 有这样一个数组&#xff1a;【0&#xff0c;4&#xff0c;2&#xff0c;3&#xff0c;3&#xff0c;1&#xff0c;2】&#xff1b;假设实现了这样一个sort()排序方法&#xff0c; 将数组二分成左右两等分&#xff0c;使用so…

数学建模~~~SPSS相关和回归分析

目录 1.双变量相关分析 1.1理论基础 1.2简单散点图的绘制介绍 1.3相关性分析 1.4分析相关性结果 2.简单线性回归分析 2.1简单概括 2.2分析过程 2.3结果分析 3.曲线回归分析 3.1问题介绍 3.2分析过程 3.3结果分析 1.双变量相关分析 1.1理论基础 双变量相关分析并不…

十七、(正点原子)Linux LCD驱动

一、Framebuffer设备 在 Linux 中应用程序通过操作 RGB LCD 的显存来实现在 LCD 上显示字符、图片等信息。 先来看一下裸机 LCD 驱动如下&#xff1a; ①、初始化 I.MX6U 的 eLCDIF 控制器&#xff0c;重点是 LCD 屏幕宽(width)、高(height)、 hspw、 hbp、 hfp、 vspw…

【MySQL进阶之路 | 高级篇】索引失效

1. SQL查询优化 我们可以从下面几个方面进行数据库调优&#xff1a; 索引失效&#xff0c;没有充分利用到索引-->索引建立关联查询太多JOIN-->SQL优化服务器调优及各个参数设置-->调整my.cnf数据过多-->分库分表 虽然SQL查询优化的技术很多&#xff0c;但大方向…

Google最新开源大语言模型:Gemma 2介绍及其微调(上篇)

引言 简介 Gemma 2模型介绍 架构设计 训练方法 后训练优化 关键发现:知识蒸馏的影响 性能评估 使用 体验&#xff1a;Hugging Chat 如何提示 Gemma 2 基于Hugging Face Transformers 结论与展望 模型汇总 引言 两岸荔枝红&#xff0c;万家烟雨中。 小伙伴们好&am…