“实模式--保护模式--实模式”转换过程
下面以pmtest2.asm为例,来讲述“实模式--保护模式--实模式”的转换过程。
1、“实模式--保护模式--实模式”的转换过程。
2、介绍段描述符属性
3、pm.inc 中的宏定义
4、pmtest2.asm源代码
一、“实模式--保护模式--实模式”的转换过程
1、“实模式--保护模式”的跳转
(1)关中断
(2)打开地址线A20
(3)置cr0寄存器的末位为1
(4)实现跳转,进入到保护模式
2、“保护模式--实模式”的跳转
(1)从保护模式下的32位代码段跳转到16位代码段
(2)在16位代码段下初始化所有段寄存器
(3)置cr0的末位为0
(4)实现跳转,返回到实模式
3、pmtest2.asm中“实模式--保护模式--实模式”的跳转过程
(1)下面是“实模式--保护模式--实模式”的跳转过程图
其中 LABEL_BEGIN、LABEL_REAL_ENTRY运行于实模式下;LEBEL_SEG_CODE32、LABEL_SEG_CODE16运行于保护模式下。所以该程序实现了“实模式--保护模式--实模式”的跳转。
(2)“实模式--保护模式”的跳转
这个跳转过程主要存在于LABEL_BEGIN代码段中:
70- 71行:保存实模式下的SP内的值
73-111行:初始化段描述符
113-121行:加载GDTR
123-124行:关中断
126-129行:打开地址线A20
141-144行:准备切换到保护模式,置cr0的末位为1
146-147行:跳转到保护模式
(3)“保护模式--实模式”的跳转
208-209行:从保护模式下的32位代码段跳转到16位代码段
316-322行:为跳回实模式做准备,将段寄存器初始化为符合实模式下的代码段规范。即用SelectorNormal来初始化段寄存器。
324-326行:置cr0的末位为0
328-329行:实现跳转,进入到实模式下的 LABEL_REAL_ENTRY段
158-158行:恢复实模式下的SP
160-162行:关闭A20地址线
164-164行:开中断
166-168行:返回DOS
二、段描述符的属性
段描述符属性占5、6字节,其具体特性如下:
在这里主要介绍第5字节的内容。
1、 P:存在(Present)位。
1 表示段在内存中存在
0 表示段在内存中不存在
2、 DPL:表示描述符特权级(Descriptor Privilege level),共2位。
它规定了所描述段的特权级,用于特权检查,以决定对该段能否访问。
3、 S:说明描述符的类型。
1 数据段和代码段描述符
0系统段描述符和门描述符
4、 TYPE:说明存储段描述符所描述的存储段的具体属性
数据段类型:
类型值 说明
---------------------------------
0 只读
1 只读、已访问
2 读/写
3 读/写、已访问
4 只读、向下扩展
5 只读、向下扩展、已访问
6 读/写、向下扩展
7 读/写、向下扩展、已访问
代码段类型:
类型值 说明
---------------------------------
8 只执行
9 只执行、已访问
A 执行/读
B 执行/读、已访问
C 只执行、一致码段
D 只执行、一致码段、已访问
E 执行/读、一致码段
F 执行/读、一致码段、已访问
系统段类型:
类型编码 说明
----------------------------------
0 <未定义>
1 可用286TSS
2 LDT
3 忙的286TSS
4 286调用门
5 任务门
6 286中断门
7 286陷阱门
8 未定义
9 可用386TSS
A <未定义>
B 忙的386TSS
C 386调用门
D <未定义>
E 386中断门
F 386陷阱门
三、pm.inc中的宏定义
在程序中,我们定义属性时,使用了pm.inc中的宏定义DA_DRW、DA_C、DA_32、DA_DRW、DA_DRWA。下面让我来向大家解释这些宏定义。
DA : Descriptor Attribute
D : 数据段
C : 代码段
S : 系统段
R : 只读
RW : 读写
A : 已访问
-----------------------------------------------------------
DA_32 EQU 4000h ; 32 位段
DA_DPL0 EQU 00h ; DPL = 0
DA_DPL1 EQU 20h ; DPL = 1
DA_DPL2 EQU 40h ; DPL = 2
DA_DPL3 EQU 60h ; DPL = 3
-----------------------------------------------------------
存储段描述符类型值说明
-----------------------------------------------------------
DA_DR EQU 90h ; 存在的只读数据段类型值
DA_DRW EQU 92h ; 存在的可读写数据段属性值
DA_DRWA EQU 93h ; 存在的已访问可读写数据段类型值
DA_C EQU 98h ; 存在的只执行代码段属性值
DA_CR EQU 9Ah ; 存在的可执行可读代码段属性值
DA_CCO EQU 9Ch ; 存在的只执行一致代码段属性值
DA_CCOR EQU 9Eh ; 存在的可执行可读一致代码段属性值
-----------------------------------------------------------
系统段描述符类型值说明
-----------------------------------------------------------
DA_LDT EQU 82h ; 局部描述符表段类型值
DA_TaskGate EQU 85h ; 任务门类型值
DA_386TSS EQU 89h ; 可用 386 任务状态段类型值
DA_386CGate EQU 8Ch ; 386 调用门类型值
DA_386IGate EQU 8Eh ; 386 中断门类型值
DA_386TGate EQU 8Fh ; 386 陷阱门类型值
四、pmtest2.asm源代码:
;=====================================================
;pmtest2.asm
;编译方法:nasm pmtest2.asm -o pmtest2.com%include "pm.inc" ;常量,宏,以及一些说明org 0100hjmp LABEL_BEGIN[SECTION .gdt]
;GDT
; 段基址 段界限 段属性
LABEL_GDT: Descriptor 0, 0, 0 ;空描述符
LABEL_DESC_NORMAL: Descriptor 0, 0ffffh, DA_DRW ;Normal描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C + DA_32 ;非一致代码段,32
LABEL_DESC_CODE16: Descriptor 0, 0ffffh, DA_C ;非一致代码段,16
LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW + DA_DPL1 ;Data
LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA + DA_32 ;Stack,32位
LABEL_DESC_TEST: Descriptor 0500000h, 0ffffh, DA_DRW ;测试代码段
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ;显存首地址
;GDT 结束GdtLen equ $ - LABEL_GDT ;GDT长度
GdtPtr dw GdtLen - 1 ;GDT界限dd 0 ;GDT基地址;GDT选择子
SelectorNormal equ LABEL_DESC_NORMAL - LABEL_GDT
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorCode16 equ LABEL_DESC_CODE16 - LABEL_GDT
SelectorData equ LABEL_DESC_DATA - LABEL_GDT + SA_RPL3
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorTest equ LABEL_DESC_TEST - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
;END of [SECTION .gdt][SECTION .data1] ;数据段
ALIGN 32
[BITS 32]
LABEL_DATA:
SPValueInRealMode dw 0
;字符串
PMMessage: db "In Protect Mode now.", 0 ;进入保护模式后显示该字符串
OffsetPMMessage equ PMMessage - $StrTest: db "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0
OffsetStrTest equ StrTest - $DataLen equ $ - LABEL_DATA
;END of [SECTION .data1];全局堆栈段
[SECTION .gs]
ALIGN 32
[BITS 32]
LABEL_STACK:times 512 db 0
TopOfStack equ $ - LABEL_STACK - 1
;END of [SECTION .gs][SECTION .s16]
[BITS 16]
LABEL_BEGIN:mov ax, csmov ds, axmov es, axmov ss, axmov sp, 0100hmov [LABEL_GO_BACK_TO_REAL + 3], axmov [SPValueInRealMode], sp;初始化16位代码段描述符mov ax, csmovzx eax, axshl eax, 4add eax, LABEL_SEG_CODE16mov word[LABEL_DESC_CODE16+2], axshr eax, 16mov byte[LABEL_DESC_CODE16+4], almov byte[LABEL_DESC_CODE16+7], ah;初始化32位代码段描述符xor 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], ah;初始化数据段描述符xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_DATAmov word[LABEL_DESC_DATA+2], axshr eax, 16mov byte[LABEL_DESC_DATA+4], almov byte[LABEL_DESC_DATA+7], ah;初始化堆栈段描述符xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_STACKmov word[LABEL_DESC_STACK+2], axshr eax, 16mov byte[LABEL_DESC_STACK+4], almov byte[LABEL_DESC_STACK+7], ah;为加载GDTR作准备xor eax, eaxmov ax, dsshl eax, 4add eax, LABEL_GDT ; eax <- gdtmov dword[GdtPtr+2], eax ; [GdtPtr+2] <- gdt 基地址;加载GDTRlgdt [GdtPtr];关中断cli;打开地址线A20in al, 92hor al, 00000010bout 92h, al;清屏操作(用以指定色彩)mov ah, 06H ;功能06H和07H mov ch, 00 ;功能描述:初始化屏幕或滚屏mov cl, 00 ;入口参数:AH=06H——向上滚屏,07H——向下滚屏mov dh, 24 ;AL=滚动行数(0——清窗口)mov dl, 79 ;BH=空白区域的缺省属性mov bh, 7 ;(CH、CL)=窗口的左上角位置(Y坐标,X坐标)mov al, 00 ;(DH、DL)=窗口的右下角位置(Y坐标,X坐标)int 10H ;出口参数:无;准备切换到保护模式mov eax, cr0or eax, 1mov cr0, eax;真正进入保护模式jmp dword SelectorCode32:0 ;执行这一句会把SelectorCode32装入cs,并跳转到SelectorCode32:0处;......................................................................
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,LABEL_REAL_ENTRY: ;从保护模式跳回到实模式就到了这里mov ax, csmov ds, axmov es, axmov ss, axmov sp, [SPValueInRealMode]in al, 92h ;关闭A20地址线and al, 11111101b out 92h, alsti ;开中断;回到DOSmov ax, 4C00hint 21h;
;END of [SECTION .s16][SECTION .s32] ;32位代码段,由实模式跳入
[BITS 32]LABEL_SEG_CODE32:mov ax, SelectorDatamov ds, ax ;数据段选择子mov ax, SelectorTestmov es, ax ;测试段选择子mov ax, SelectorVideo mov gs, ax ;视频段选择子mov ax, SelectorStackmov ss, ax ;堆栈段选择子mov esp, TopOfStack;下面显示一个字符串mov ah, 0Ch ;0000:黑底 1100:红字xor esi, esixor edi, edimov esi, OffsetPMMessage ;源数据偏移mov edi, (80*10+0)*2 ;目的数据偏移。屏幕第10行,第0列cld
.1:lodsbtest al, aljz .2mov [gs:edi], ax ;将ax中的数据送入到显存add edi, 2jmp .1
.2: ;显示完毕call DispReturncall TestReadcall TestWriteCall TestRead;到此停止jmp SelectorCode16:0
;---------------------------------------------------------------------------TestRead:xor esi, esimov ecx, 8
.loop:mov al, [es:esi]call DispALinc esiloop .loopcall DispReturnret
;TestRead结束--------------------------------------------------------------;--------------------------------------------------------------------------
TestWrite:push esipush edixor esi, esixor edi, edimov esi, OffsetStrTest ;源数据偏移.1:lodsbtest al, aljz .2mov [es:edi], alinc edijmp .1
.2:pop edipop esiret;TestWrite结束--------------------------------------------------------------;---------------------------------------------------------------------------
;显示AL中的数字
;默认地:
; 数字已经存在AL中
; edi始终指向要显示的下一个字符的位置
;被改变的寄存器
; ax, edi
;---------------------------------------------------------------------------DispAL:push ecxpush edxmov ah, 0Chmov dl, alshr al, 4mov ecx, 2
.begin:and al, 01111bcmp al, 9ja .1add al, '0'jmp .2
.1:sub al, 0Ahadd al, 'A'
.2:mov [gs:edi], axadd edi, 2mov al, dlloop .beginadd edi, 2pop edxpop ecxret
;DispAL结束-----------------------------------------------------------------;---------------------------------------------------------------------------
DispReturn:push eaxpush ebxmov eax, edimov bl, 160div bland eax, 0FFhinc eaxmov bl, 160mul blmov edi, eaxpop ebxpop eaxret
;DispReturn结束--------------------------------------------------------------SegCode32Len equ $ - LABEL_SEG_CODE32
; END of [SECTION .s32];16位代码段,由32位代码段跳入,跳出后到实模式
[SECTION .s16code]
ALIGN 32
[BITS 16]
LABEL_SEG_CODE16:;跳回实模式:mov ax, SelectorNormalmov ds, axmov es, axmov fs, axmov gs, axmov ss, axmov eax, cr0and al, 11111110bmov cr0, eaxLABEL_GO_BACK_TO_REAL:jmp 0:LABEL_REAL_ENTRY ;段地址会在程序开始处被设置成正确的值Code16Len equ $-LABEL_SEG_CODE16
;END of [SECTION .s16code]
“实模式--保护模式--实模式”转换过程相关推荐
- (实模式+保护模式)模式切换的过程步骤(代码+文字解析)
[0]写在前面 文末的个人总结是干货,前面代码仅供参考的,且source code from orange's implemention of a os. ; ==================== ...
- 实模式、保护模式和虚拟8086模式
参考自:实模式与保护模式解惑之(一)--二者的起源与区别(河西无名式) 概述:实模式和保护模式是处理器发展的两个非常重要的阶段.这两个模式下的编程也有着显著的不同,弄明实模式与保护模式的区别是理解操作 ...
- (操作系统开发)从实模式---->保护模式---->IA-32e模式( 64位模式)
实模式和保护模式都是CPU的工作模式. 实模式与保护模式介绍 在实模式下,程序可以操作任何地址空间,而且无法限制程序的执行权限.尽管这种模式给设置硬件功能带来许多方便,但却给程序执行的安全性和稳定性带 ...
- 计算机实训基地运行与管理,计算机实训基地一体化管理模式探讨论文
计算机实训基地一体化管理模式探讨论文 1高校计算机实训基地平时的工作内容 1.1实训基地的日常管理 高校设立了独立的计算机教学楼,并在计算机楼里开设了开放计算机实验室,在计算机教学楼里,配有专门的管理 ...
- 实体型转换为一个关系模式
转载自:http://iask.sina.com.cn/b/18107163.html 1.一个实体型转换为一个关系模式.实体的属性就是关系的属性.实体的码就是关系的码.2.一个联系转化为一个关系模式 ...
- [实训笔记] 01 软件架构模式
第 1 讲 软件模式架构 1.软件架构模式概念 1.1 架构是什么 定义 架构是构成一个系统的基础组织结构,包括系统的组件构成,组件间的相互关系.系统和其所在的关系.以及指导架构设计和演进的相关准则. ...
- 驱动程序9--实模式,保护模式,虚拟8086模式
from:http://blog.sina.com.cn/s/blog_61d65e360100glqy.html 驱动程序9--实模式,保护模式,虚拟8086模式 (2010-01-07 00:23 ...
- 腾讯视频怎样开启深色模式保护眼睛
1.点击打开腾讯视频软件,如图; 腾讯视频怎样开启深色模式保护眼睛 2.然后在软件首页点击[个人中心],如图; 腾讯视频怎样开启深色模式保护眼睛 3.进入[个人中心]界面,往下滑找到[设置]选项点击, ...
- 数据库系统概论-第一章绪论【概念模型、层次模型和三级模式(外模式、模式、内模式)】
1,数据系统概述 数据库的四个基本概念: 数据.数据库.数据库管理系统.数据库系统: 1 数据: 描述事物的符号记录称为数据 2 数据库是长期存储在计算机内.有组织.可共享的大量数据的集合. 3 数据 ...
最新文章
- 实战篇:Security+JWT组合拳 | 附源码
- 与工作流关联的服务器发生意外错误
- 机房监控系统解说--发电机篇
- HttpHelps类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理...
- html5表单实现简单计算器
- Vue服务端配置示例
- python调用jenkinsAPI构建jenkins,并传递参数
- 下载Windows10纯净官方镜像
- keytool条目_keytool常用命令
- 记录一下阿里云购买域名遇到的坑
- c语言程序函数由什么两部分组成,C语言中一个函数由函数首部和_____两部分组成. 答案:函数体...
- 数据库系统的结构和组成
- [转载] 晓说——第25期:看美国系列之“两极分化的黑人”
- 软测项目辅导综合教程
- Android多媒体添加软解码
- 什么是聚合路由器、聚合路由器有什么用
- 如何禁止福昕阅读器改变PDF页面缩放比例?
- 解决项目部署到阿里云服务器邮件发送失败的方法
- Python实现多电阻并联快捷计算
- poi读取Excel时日期为数字 的解决方法
热门文章
- Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)
- Windows核心编程 第三章 内核对象
- C语言经典例4-某一天是这一年的第几天
- 【数字信号处理】序列傅里叶变换 ( 基本序列的傅里叶变换 | 单位脉冲序列 δ(n) 傅里叶变换 )
- 【Android Gradle 插件】settings.gradle 配置文件 ( 配置基本作用 | include 函数用法 | 目录层级配置 | 修改 Module 模块构建脚本名称 )
- 【Windows 逆向】使用 CE 工具挖掘关键数据内存真实地址 ( 完整流程演示 | 查找临时内存地址 | 查找真实指针地址 )
- jQuery Mobile Slider Widget 使用js控制
- 问候Maven3(笔记一)
- express-14 发送邮件
- VS2017学习OpenGL时遇到的一些小问题和解决方法