下面以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]

“实模式--保护模式--实模式”转换过程相关推荐

  1. (实模式+保护模式)模式切换的过程步骤(代码+文字解析)

    [0]写在前面 文末的个人总结是干货,前面代码仅供参考的,且source code from orange's implemention of a os. ; ==================== ...

  2. 实模式、保护模式和虚拟8086模式

    参考自:实模式与保护模式解惑之(一)--二者的起源与区别(河西无名式) 概述:实模式和保护模式是处理器发展的两个非常重要的阶段.这两个模式下的编程也有着显著的不同,弄明实模式与保护模式的区别是理解操作 ...

  3. (操作系统开发)从实模式---->保护模式---->IA-32e模式( 64位模式)

    实模式和保护模式都是CPU的工作模式. 实模式与保护模式介绍 在实模式下,程序可以操作任何地址空间,而且无法限制程序的执行权限.尽管这种模式给设置硬件功能带来许多方便,但却给程序执行的安全性和稳定性带 ...

  4. 计算机实训基地运行与管理,计算机实训基地一体化管理模式探讨论文

    计算机实训基地一体化管理模式探讨论文 1高校计算机实训基地平时的工作内容 1.1实训基地的日常管理 高校设立了独立的计算机教学楼,并在计算机楼里开设了开放计算机实验室,在计算机教学楼里,配有专门的管理 ...

  5. 实体型转换为一个关系模式

    转载自:http://iask.sina.com.cn/b/18107163.html 1.一个实体型转换为一个关系模式.实体的属性就是关系的属性.实体的码就是关系的码.2.一个联系转化为一个关系模式 ...

  6. [实训笔记] 01 软件架构模式

    第 1 讲 软件模式架构 1.软件架构模式概念 1.1 架构是什么 定义 架构是构成一个系统的基础组织结构,包括系统的组件构成,组件间的相互关系.系统和其所在的关系.以及指导架构设计和演进的相关准则. ...

  7. 驱动程序9--实模式,保护模式,虚拟8086模式

    from:http://blog.sina.com.cn/s/blog_61d65e360100glqy.html 驱动程序9--实模式,保护模式,虚拟8086模式 (2010-01-07 00:23 ...

  8. 腾讯视频怎样开启深色模式保护眼睛

    1.点击打开腾讯视频软件,如图; 腾讯视频怎样开启深色模式保护眼睛 2.然后在软件首页点击[个人中心],如图; 腾讯视频怎样开启深色模式保护眼睛 3.进入[个人中心]界面,往下滑找到[设置]选项点击, ...

  9. 数据库系统概论-第一章绪论【概念模型、层次模型和三级模式(外模式、模式、内模式)】

    1,数据系统概述 数据库的四个基本概念: 数据.数据库.数据库管理系统.数据库系统: 1 数据: 描述事物的符号记录称为数据 2 数据库是长期存储在计算机内.有组织.可共享的大量数据的集合. 3 数据 ...

最新文章

  1. 实战篇:Security+JWT组合拳 | 附源码
  2. 与工作流关联的服务器发生意外错误
  3. 机房监控系统解说--发电机篇
  4. HttpHelps类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理...
  5. html5表单实现简单计算器
  6. Vue服务端配置示例
  7. python调用jenkinsAPI构建jenkins,并传递参数
  8. 下载Windows10纯净官方镜像
  9. keytool条目_keytool常用命令
  10. 记录一下阿里云购买域名遇到的坑
  11. c语言程序函数由什么两部分组成,C语言中一个函数由函数首部和_____两部分组成. 答案:函数体...
  12. 数据库系统的结构和组成
  13. [转载] 晓说——第25期:看美国系列之“两极分化的黑人”
  14. 软测项目辅导综合教程
  15. Android多媒体添加软解码
  16. 什么是聚合路由器、聚合路由器有什么用
  17. 如何禁止福昕阅读器改变PDF页面缩放比例?
  18. 解决项目部署到阿里云服务器邮件发送失败的方法
  19. Python实现多电阻并联快捷计算
  20. poi读取Excel时日期为数字 的解决方法

热门文章

  1. Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)
  2. Windows核心编程 第三章 内核对象
  3. C语言经典例4-某一天是这一年的第几天
  4. 【数字信号处理】序列傅里叶变换 ( 基本序列的傅里叶变换 | 单位脉冲序列 δ(n) 傅里叶变换 )
  5. 【Android Gradle 插件】settings.gradle 配置文件 ( 配置基本作用 | include 函数用法 | 目录层级配置 | 修改 Module 模块构建脚本名称 )
  6. 【Windows 逆向】使用 CE 工具挖掘关键数据内存真实地址 ( 完整流程演示 | 查找临时内存地址 | 查找真实指针地址 )
  7. jQuery Mobile Slider Widget 使用js控制
  8. 问候Maven3(笔记一)
  9. express-14 发送邮件
  10. VS2017学习OpenGL时遇到的一些小问题和解决方法