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

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

相关文章

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

C#实现高性能拍照与水印添加功能完整方案

《C#实现高性能拍照与水印添加功能完整方案》在工业检测、质量追溯等应用场景中,经常需要对产品进行拍照并添加相关信息水印,本文将详细介绍如何使用C#实现一个高性能的拍照和水印添加功能,包含完整的代码实现... 目录1. 概述2. 功能架构设计3. 核心代码实现python3.1 主拍照方法3.2 安全HBIT

录音功能在哪里? 电脑手机等设备打开录音功能的技巧

《录音功能在哪里?电脑手机等设备打开录音功能的技巧》很多时候我们需要使用录音功能,电脑和手机这些常用设备怎么使用录音功能呢?下面我们就来看看详细的教程... 我们在会议讨论、采访记录、课堂学习、灵感创作、法律取证、重要对话时,都可能有录音需求,便于留存关键信息。下面分享一下如何在电脑端和手机端上找到录音功能

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转

基于Java和FFmpeg实现视频压缩和剪辑功能

《基于Java和FFmpeg实现视频压缩和剪辑功能》在视频处理开发中,压缩和剪辑是常见的需求,本文将介绍如何使用Java结合FFmpeg实现视频压缩和剪辑功能,同时去除数据库操作,仅专注于视频处理,需... 目录引言1. 环境准备1.1 项目依赖1.2 安装 FFmpeg2. 视频压缩功能实现2.1 主要功

使用Python实现无损放大图片功能

《使用Python实现无损放大图片功能》本文介绍了如何使用Python的Pillow库进行无损图片放大,区分了JPEG和PNG格式在放大过程中的特点,并给出了示例代码,JPEG格式可能受压缩影响,需先... 目录一、什么是无损放大?二、实现方法步骤1:读取图片步骤2:无损放大图片步骤3:保存图片三、示php

深度解析Python yfinance的核心功能和高级用法

《深度解析Pythonyfinance的核心功能和高级用法》yfinance是一个功能强大且易于使用的Python库,用于从YahooFinance获取金融数据,本教程将深入探讨yfinance的核... 目录yfinance 深度解析教程 (python)1. 简介与安装1.1 什么是 yfinance?