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

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

相关文章

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体

Java Web实现类似Excel表格锁定功能实战教程

《JavaWeb实现类似Excel表格锁定功能实战教程》本文将详细介绍通过创建特定div元素并利用CSS布局和JavaScript事件监听来实现类似Excel的锁定行和列效果的方法,感兴趣的朋友跟随... 目录1. 模拟Excel表格锁定功能2. 创建3个div元素实现表格锁定2.1 div元素布局设计2.

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

苹果macOS 26 Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色

《苹果macOS26Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色》在整体系统设计方面,macOS26采用了全新的玻璃质感视觉风格,应用于Dock栏、应用图标以及桌面小部件等多个界面... 科技媒体 MACRumors 昨日(6 月 13 日)发布博文,报道称在 macOS 26 Tahoe 中

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

MybatisPlus service接口功能介绍

《MybatisPlusservice接口功能介绍》:本文主要介绍MybatisPlusservice接口功能介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录Service接口基本用法进阶用法总结:Lambda方法Service接口基本用法MyBATisP