保护模式超强的寻址功能:天空任鸟飞

2024-04-30 22:48

本文主要是介绍保护模式超强的寻址功能:天空任鸟飞,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

X86架构下,cpu 的运行模式分两种,一种是实模式,像早期Dos那种黑底白字的命令行操作界面,可以说是实模式最好表现形式,在实模式下也只能产生这种冰冷,呆板,机械的用户体验。后来Intel的CPU进一步发展,引入了保护模式,由此,操作系统的发展进入了新的时代,在保护模式下,CPU功能进一步增强,进而支撑的起计算量繁重的图形用户界面,我们这才有了温暖,炫酷,友好的图形操作系统,微软也正是靠80386处理器提供的保护模式功能,开发出win3.1,及后来享誉世界的win95,从而奠定其软件行业的垄断地位。

保护模式之所以能提供强大的处理能力,一方面要得益于增强了的寻址能力,在实模式下,cpu只能处理最多16位的数据,同时地址总线也就20位,因此能访问的最大内存也就2^20 字节,也就是1M多,在保护模式下,cpu可以处理32位的数据,同时地址总线也扩张到32位,这样,cpu能访问的内存就可以一下子达到4G.

Intel 8086 cpu,使用16位寄存器,16位数据总线,20位的地址总线,它的寻址方式是由段和偏移两部分组成,具体物理地址是这么计算的:

物理地址 = 段值 * 16 + 偏移

段值和偏移都只能用16位来表示,段值16位,16是等于2^4,所以段值*16也就相当于一个20位的数字,由此段值*16的数值不会超过1M,而偏移16位,能表示的地址范围也就不超过4K,因此整个物理地址能抵达的范围也就是1M + 4k.

在保护模式下,寻址方式完全就不同了,我们上一节讲过的GDT,全局描述符表,该表的表项就叫描述符(descriptor),在描述符中,专门抽出4个字节,也就是32位数据来表示内存的基地址,这样,内存访问一下子就达到了4G,在原来的实模式下,cs, ds这些16位的寄存器往往用来存储段值,在保护模式下,这些寄存器用来存储指向GDT某个描述符的索引。在保护模式下,访问某处的内存时,仍然使用寄存器:偏移 的方式,但是CPU的对地址的计算方法不再使用上面的公式,而是把寄存器中的值当做访问GDT的索引,在GDT中找到对应的描述符,从描述符中获得要访问内存的基地址,然后将基地址加上偏移,进而得到要访问的具体地址。由此,就突破了上面寻址公式的1M范围限制。如果我们在GDT中设置一个描述符,这个描述符所描述的基地址设置为5M,那么当我们用寄存器指向这个描述符时,系统就能够读取5M以上的内存了

根据上一节内容
(http://blog.csdn.net/tyler_download/article/details/52021120),

我们可以构造一个指向5M内存地址的描述符:

LABEL_DESC_5M: Descriptor 0500000h, 0ffffh, DA_DRW

0500000h = 5 * (2^20), 2^20 相当于1M, 于是0500000h相当于5M.接下来我们做一个实验,先将一段数据写入到5M的内存地址,然后再读取写入的数据,将读到的数据显示到屏幕上。下面就是我们要写的内核代码(boot_read5M.asm):

 %include "pm.inc"org   0x7c00jmp   LABEL_BEGIN[SECTION .gdt];                                  段基址          段界限                属性
LABEL_GDT:          Descriptor        0,            0,                   0  
LABEL_DESC_CODE32:  Descriptor        0,      SegCode32Len - 1,       DA_C + DA_32
LABEL_DESC_VIDEO:   Descriptor     0B8000h,         0ffffh,           DA_DRW
LABEL_DESC_5M:      Descriptor     0500000h,        0ffffh,           DA_DRWGdtLen     equ    $ - LABEL_GDT
GdtPtr     dw     GdtLen - 1dd     0SelectorCode32    equ   LABEL_DESC_CODE32 -  LABEL_GDT
SelectorVideo     equ   LABEL_DESC_VIDEO  -  LABEL_GDT
Selector5M        equ   LABEL_DESC_5M - LABEL_GDT[SECTION  .s16]
[BITS  16]
LABEL_BEGIN:mov   ax, csmov   ds, axmov   es, axmov   ss, axmov   sp, 0100hxor   eax, eaxmov   ax,  csshl   eax, 4add   eax, LABEL_SEG_CODE32mov   word [LABEL_DESC_CODE32 + 2], axshr   eax, 16mov   byte [LABEL_DESC_CODE32 + 4], almov   byte [LABEL_DESC_CODE32 + 7], ahxor   eax, eaxmov   ax, dsshl   eax, 4add   eax,  LABEL_GDTmov   dword  [GdtPtr + 2], eaxlgdt  [GdtPtr]cli   ;关中断in    al,  92hor    al,  00000010bout   92h, almov   eax, cr0or    eax , 1mov   cr0, eaxjmp   dword  SelectorCode32: 0[SECTION .s32][BITS  32]
LABEL_SEG_CODE32:mov   ax, SelectorVideomov   gs, axmov   si, msgmov   ax, Selector5M    ;用 es 指向5M内存描述符mov   es, axmov   edi, 0write_msg_to_5M:  ;将si指向的字符一个个写到5M内存处cmp   byte [si], 0je    prepare_to_show_charmov   al, [si]mov   [es:edi], aladd   edi, 1add   si, 1jmp   write_msg_to_5Mprepare_to_show_char:mov   ebx, 10mov   ecx, 2mov   si, 0showChar:mov   edi, (80*11)add   edi, ebxmov   eax, edimul   ecxmov   edi, eaxmov   ah, 0chmov   al, [es:si]  ;由于es指向描述符LABEL_DESC_5M, 所以es:si 表示的地址是从5M开始的内存,si表示从5M开始后的偏移cmp   al, 0je    endadd   ebx,1add   si, 1mov   [gs:edi], axjmp   showChar
end: jmp   $msg:DB     "This string is writeen to 5M memory", 0SegCode32Len   equ  $ - LABEL_SEG_CODE32

首先,我们增加了一个描述符Selector5M,用来指向5M以外的内存地址,在 write_msg_to_5M 中,由于es存储的是描述符LABEL_DESC_5M在GDT中的偏移,同时edi 初始化为0, 因此[es:edi]表示从5M开始,偏移为0处的地址,mov [es:edi] , al, 就是将al的内容写入到5M偏移为0处的内存,也就是0500000h处的内存,每次循环edi都加1,于是第二次循环便将al的内容写入到内存0500001h处,依次类推。

在showChar中,语句al, [es:si] 就是将5M内存处的数据读入到al中,一开始si初始化为0,所以第一次运行showChar代码,这一句将0500000h内存处的1字节数据存入al, 然后si加1,那么第二次运行时,该语句将0500001h内存处的字节信息写入到al, 依次类推

这样,整个内核的逻辑是先将字符串写入到5M起始的内存处,然后再从5M内存处,将信息读取出来,显示到屏幕上。

整个项目的代码可以在以下github地址下载:
https://github.com/wycl16514/os-kernel-read-out-of-5M

项目下载后,内容如下:
这里写图片描述

整个项目是一个java项目,先把这个目录import到eclipse里面,cd到这个目录,使用命令行:

nasm -o boot.bat boot_read5M.asm

将汇编代码编译成可执行的二进制文件:
这里写图片描述

然后在eclipse中运行java工程,这样会在目录下生产虚拟软盘文件system.img, boot.bat的内容会写入到这个虚拟软盘的第一扇区,做完上面步骤后,在工程目录下回生成以下文件:
这里写图片描述

最后用虚拟机加载虚拟软盘文件system.img,运行虚拟机结果如下:
这里写图片描述

可见,我们的内核确实将数据写入到5M内存处,然后再将数据读取出来,显示到屏幕上。

本节,我们显示了保护模式下,强大的内存寻址功能,保护模式是一个很复杂的技术要点,保护模式的其他功能我们在后面开发系统内核用到时再详细学习。进入保护模式后,有一个巨大的好处是,我们可以引入C语言来开发内核,下一节的内容就是,如何使用C语言来开发操作系统的内核。

这篇关于保护模式超强的寻址功能:天空任鸟飞的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/950116

相关文章

SpringKafka消息发布之KafkaTemplate与事务支持功能

《SpringKafka消息发布之KafkaTemplate与事务支持功能》通过本文介绍的基本用法、序列化选项、事务支持、错误处理和性能优化技术,开发者可以构建高效可靠的Kafka消息发布系统,事务支... 目录引言一、KafkaTemplate基础二、消息序列化三、事务支持机制四、错误处理与重试五、性能优

SpringIntegration消息路由之Router的条件路由与过滤功能

《SpringIntegration消息路由之Router的条件路由与过滤功能》本文详细介绍了Router的基础概念、条件路由实现、基于消息头的路由、动态路由与路由表、消息过滤与选择性路由以及错误处理... 目录引言一、Router基础概念二、条件路由实现三、基于消息头的路由四、动态路由与路由表五、消息过滤

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

基于SpringBoot实现文件秒传功能

《基于SpringBoot实现文件秒传功能》在开发Web应用时,文件上传是一个常见需求,然而,当用户需要上传大文件或相同文件多次时,会造成带宽浪费和服务器存储冗余,此时可以使用文件秒传技术通过识别重复... 目录前言文件秒传原理代码实现1. 创建项目基础结构2. 创建上传存储代码3. 创建Result类4.

Python+PyQt5实现多屏幕协同播放功能

《Python+PyQt5实现多屏幕协同播放功能》在现代会议展示、数字广告、展览展示等场景中,多屏幕协同播放已成为刚需,下面我们就来看看如何利用Python和PyQt5开发一套功能强大的跨屏播控系统吧... 目录一、项目概述:突破传统播放限制二、核心技术解析2.1 多屏管理机制2.2 播放引擎设计2.3 专

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

Python实战之屏幕录制功能的实现

《Python实战之屏幕录制功能的实现》屏幕录制,即屏幕捕获,是指将计算机屏幕上的活动记录下来,生成视频文件,本文主要为大家介绍了如何使用Python实现这一功能,希望对大家有所帮助... 目录屏幕录制原理图像捕获音频捕获编码压缩输出保存完整的屏幕录制工具高级功能实时预览增加水印多平台支持屏幕录制原理屏幕

Python实现自动化表单填写功能

《Python实现自动化表单填写功能》在Python中,自动化表单填写可以通过多种库和工具实现,本文将详细介绍常用的自动化表单处理工具,并对它们进行横向比较,可根据需求选择合适的工具,感兴趣的小伙伴跟... 目录1. Selenium简介适用场景示例代码优点缺点2. Playwright简介适用场景示例代码

MySQL中闪回功能的方案讨论及实现

《MySQL中闪回功能的方案讨论及实现》Oracle有一个闪回(flashback)功能,能够用户恢复误操作的数据,这篇文章主要来和大家讨论一下MySQL中支持闪回功能的方案,有需要的可以了解下... 目录1、 闪回的目标2、 无米无炊一3、 无米无炊二4、 演示5、小结oracle有一个闪回(flashb