交流
商城
MCN
登入
注册
首页
提问
分享
讨论
建议
公告
动态
发表新帖
发表新帖
1 保护模式
分享
未结
0
2645
李延
LV6
2022-10-30
悬赏:20积分
# 1 什么是保护模式 我们的cpu从16位到32位也就意味着,我们的所有通用寄存器都将有32位可以使用,也就是以为着我们可寻址的内存空间从原来的 1MB扩展到了4GB。当我们有多个程序在同时运行时,如何使各种程序能够正确使用自己的内存,互不干扰。 对于这个问题,我们首先想到的解决方案就是在使用内存前先进行登记,我们程序只能使用已经登记过的内存,如果未登记的内存则程序就会报错。 基于这种思路,就有了GDT 全局段描述符表。 # 2 保护模式介绍 ## 2.1 GDT **Global Descriptor Table**(GDT) 从名字我们就可以知道它是一个表,他被保存在一块内存中,最多可以有256 项,这个表中的每项就是关于一段内存的描述:如:内存从哪里开始到哪里结束,以及它的读写权限等信息内容。 我们可以在内存的任意地方设置这个表格内容。当我们设置好GDT的内容后,可以通过汇编命令`lgdt` 来安装我们新设置的段描述符。 ```c lgdt *(关于GDT表的位置) ``` 注意lgdt 后面跟的是一个地址,这个地址指向一个48位的数值。而这48位数值代表的意思为: ```c 前16位标识GDT表有几项,后32位标识GDT表第一项地址。 ``` 这样cpu就可以知道我们将内存分为了几段。 ## 2.2 段选择子 前面我们设置的GDT 表的内容。但我们在运行程序时,如何确定当前正在运行的代码使用的时这个表的哪一项目,这个时候就需要的段寄存器来确认我们当前程序使用的是表项中的哪一个了。 在16位模式中,段寄存器记录的是当前段的基地址,但在32位模式下,段的信息都记录在了GDT表中了,所以段寄存器也就没必要在记录段基地址了,所以现在只需要记录GDT的第几项就可以了, 这样在保护模式下的段寻址过程为: - 段寄存器(也就是 段选择子)内记录了当前代码使用的是GDT的第几项 - 通过段寄存器的内容在GDT表中查询对应的段信息,获取到段基地址 - 根据段基地址与我们程序的偏移量获取到真实的物理地址 # 3 进入32位保护模式 我们要进入32位保护模式,我们需要如下几步: - 在16位模式下设置好 GDT 表内容 - 打开A20 总线 - 设置CR0寄存器的PE位 - 进行远端跳转,进入32位保护模式
回帖
消灭零回复
提交回复
热议榜
java 相关知识分享
8
好的程序员与不好的程序员
6
写给工程师的十条精进原则
5
spring boot以jar包运行配置的logback日志文件没生成
5
一步一步分析SpringBoot启动源码(一)
5
MockMvc测试
5
【吐槽向】是不是有个吐槽的板块比较好玩
4
logstash jdbc同步mysql多表数据到elasticsearch
3
IntelliJ IDEA 优质License Server
3
.gitignore忽略规则
3
SpringBoot启动源码分析
3
一步一步分析SpringBoot启动源码(三)
3
2
一步一步分析SpringBoot启动源码(二)
2
积分不够将无法发表新帖
2
官方产品
Meta-Boot - 基于MCN
MCN - 快速构建SpringBoot应用
微信扫码关注公众号