《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)...
在上次的代码基础上,添加一个代码段作为通过调用门转移的目标段。了解一下调用的工作方法,代码分析如下:
<<红色标识部分为新增代码>>
; ==========================================
; pmtest4.asm
; 编译方法:nasm pmtest4.asm -o pmtest4.com
; ==========================================%include "pm.inc" ; 常量, 宏, 以及一些说明
org 0100h
jmp 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_CODE_DEST: Descriptor 0,SegCodeDestLen-1, DA_C+DA_32; 非一致代码段,32;目标代码描述符
LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW ; Data
LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA+DA_32;Stack, 32 位
LABEL_DESC_LDT: Descriptor 0, LDTLen-1, DA_LDT ; LDT
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址; 门 目标选择子,偏移,DCount, 属性
LABEL_CALL_GATE_TEST: Gate SelectorCodeDest, 0, 0, DA_386CGate+DA_DPL0;调用门描述符DPL=0; 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
SelectorCodeDest equ LABEL_DESC_CODE_DEST - LABEL_GDT;目标代码选择子
SelectorData equ LABEL_DESC_DATA - LABEL_GDT
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorLDT equ LABEL_DESC_LDT - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDTSelectorCallGateTest equ LABEL_CALL_GATE_TEST - 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 0TopOfStack equ $ - LABEL_STACK - 1
; END of [SECTION .gs]
[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100hmov [LABEL_GO_BACK_TO_REAL+3], ax
mov [SPValueInRealMode], sp; 初始化 16 位代码段描述符
mov ax, cs
movzx eax, ax
shl eax, 4
add eax, LABEL_SEG_CODE16
mov word [LABEL_DESC_CODE16 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE16 + 4], al
mov byte [LABEL_DESC_CODE16 + 7], ah; 初始化 32 位代码段描述符
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEG_CODE32
mov word [LABEL_DESC_CODE32 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE32 + 4], al
mov byte [LABEL_DESC_CODE32 + 7], ah; 初始化测试调用门的代码段描述符
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEG_CODE_DEST
mov word [LABEL_DESC_CODE_DEST + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE_DEST + 4], al
mov byte [LABEL_DESC_CODE_DEST + 7], ah; 初始化数据段描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_DATA
mov word [LABEL_DESC_DATA + 2], ax
shr eax, 16
mov byte [LABEL_DESC_DATA + 4], al
mov byte [LABEL_DESC_DATA + 7], ah; 初始化堆栈段描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_STACK
mov word [LABEL_DESC_STACK + 2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK + 4], al
mov byte [LABEL_DESC_STACK + 7], ah; 初始化 LDT 在 GDT 中的描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_LDT
mov word [LABEL_DESC_LDT + 2], ax
shr eax, 16
mov byte [LABEL_DESC_LDT + 4], al
mov byte [LABEL_DESC_LDT + 7], ah; 初始化 LDT 中的描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_CODE_A
mov word [LABEL_LDT_DESC_CODEA + 2], ax
shr eax, 16
mov byte [LABEL_LDT_DESC_CODEA + 4], al
mov byte [LABEL_LDT_DESC_CODEA + 7], ah; 为加载 GDTR 作准备
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT ; eax <- gdt 基地址
mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址; 加载 GDTR
lgdt [GdtPtr]; 关中断
cli; 打开地址线A20
in al, 92h
or al, 00000010b
out 92h, al; 准备切换到保护模式
mov eax, cr0
or eax, 1
mov cr0, eax; 真正进入保护模式
jmp dword SelectorCode32:0 ; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0 处;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LABEL_REAL_ENTRY: ; 从保护模式跳回到实模式就到了这里
mov ax, cs
mov ds, ax
mov es, ax
mov ss, axmov sp, [SPValueInRealMode]
in al, 92h ; ┓
and al, 11111101b ; ┣ 关闭 A20 地址线
out 92h, al ; ┛sti ; 开中断
mov ax, 4c00h ; ┓
int 21h ; ┛回到 DOS
; END of [SECTION .s16][SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS 32]LABEL_SEG_CODE32:
mov ax, SelectorData
mov ds, ax ; 数据段选择子
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子mov ax, SelectorStack
mov ss, ax ; 堆栈段选择子mov esp, TopOfStack
; 下面显示一个字符串
mov ah, 0Ch ; 0000: 黑底 1100: 红字
xor esi, esi
xor edi, edi
mov esi, OffsetPMMessage ; 源数据偏移
mov edi, (80 * 10 + 0) * 2 ; 目的数据偏移。屏幕第 10 行, 第 0 列。
cld
.1:
lodsb
test al, al
jz .2
mov [gs:edi], ax
add edi, 2
jmp .1
.2: ; 显示完毕call DispReturn
; 测试调用门(无特权级变换),将打印字母 'C'
call SelectorCallGateTest:0
;call SelectorCodeDest:0 ---SelectorCallGateTest的选择子为SelectorCodeDest,偏移为0; Load LDT
mov ax, SelectorLDT
lldt axjmp SelectorLDTCodeA:0 ; 跳入局部任务,将打印字母 'L'。
; ------------------------------------------------------------------------
DispReturn:
push eax
push ebx
mov eax, edi
mov bl, 160
div bl
and eax, 0FFh
inc eax
mov bl, 160
mul bl
mov edi, eax
pop ebx
pop eaxret
; DispReturn 结束---------------------------------------------------------SegCode32Len equ $ - LABEL_SEG_CODE32
; END of [SECTION .s32][SECTION .sdest]; 调用门目标段
[BITS 32]LABEL_SEG_CODE_DEST:
;jmp $
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子(目的)mov edi, (80 * 12 + 0) * 2 ; 屏幕第 12 行, 第 0 列。
mov ah, 0Ch ; 0000: 黑底 1100: 红字
mov al, 'C'
mov [gs:edi], axretf
SegCodeDestLen equ $ - LABEL_SEG_CODE_DEST
; END of [SECTION .sdest]; 16 位代码段. 由 32 位代码段跳入, 跳出后到实模式
[SECTION .s16code]
ALIGN 32
[BITS 16]
LABEL_SEG_CODE16:
; 跳回实模式:
mov ax, SelectorNormal
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, axmov eax, cr0
and al, 11111110b
mov cr0, eaxLABEL_GO_BACK_TO_REAL:
jmp 0:LABEL_REAL_ENTRY ; 段地址会在程序开始处被设置成正确的值Code16Len equ $ - LABEL_SEG_CODE16
; END of [SECTION .s16code]
; LDT
[SECTION .ldt]
ALIGN 32
LABEL_LDT:
; 段基址 段界限 , 属性
LABEL_LDT_DESC_CODEA: Descriptor 0, CodeALen - 1, DA_C + DA_32 ; Code, 32 位LDTLen equ $ - LABEL_LDT
; LDT 选择子
SelectorLDTCodeA equ LABEL_LDT_DESC_CODEA - LABEL_LDT + SA_TIL
; END of [SECTION .ldt]; CodeA (LDT, 32 位代码段)
[SECTION .la]
ALIGN 32
[BITS 32]
LABEL_CODE_A:
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子(目的)mov edi, (80 * 13 + 0) * 2 ; 屏幕第 13 行, 第 0 列。
mov ah, 0Ch ; 0000: 黑底 1100: 红字
mov al, 'L'
mov [gs:edi], ax; 准备经由16位代码段跳回实模式
jmp SelectorCode16:0
CodeALen equ $ - LABEL_CODE_A
; END of [SECTION .la]
Gate宏的分析请见《Orange’s 一个操作系统的实现》3.保护模式1----pm.inc分析:
本代码只是展示了调用的使用方式,即提供了目标代码段的入口地址及相关附加属性(无特权级的转移),如果需要特权级的转移,则需
参照以下规则:
假设我们有代码A转移到代码B,使用一个调用G,即调用门G中的目标选择子指向代码B的段。我们涉及到这么几个要素CPL、RPL、
代码B的DPL(记做DPL_B)、调用门的DPL(记做DPL_G)。根据《Orange’s 一个操作系统的实现》3.保护模式5----特权级概述(转)
介绍可知A访问调用门G时,相当于访问一个数据段,要求CPL和RPL都小于或者等于DPL_G.换句话说,CPL和RPL须在更高的特权级上.
除此之外,还需比较CPL和DPL_B,如果是一致代码段,则要求DPL_B<=CPL;如果是非一致代码段,call和jmp指令又有所不同,使用
CALL时,要求DPL_B<=CPL;使用Jmp时,只能是DPL-B=CPL
规则如下
目标代码段 | call | jmp |
目标是一致代码段 | CPL<=DPL_G | 同CALL |
RPL<=DPL_G | 同CALL | |
DPL_B<=CPL | 同CALL | |
目标是非一致代码 | CPL<=DPL_G | CPL<=DPL_G |
RPL<=DPL_G | RPL<=DPL_G | |
DPL_B<=CPL | DPL_B=CPL |
综上:通过调用门和call指令,可以实现从低特权级到高特权级的转移,无论目标代码是一致的还是非一致的
转载于:https://www.cnblogs.com/Aoysme/archive/2011/01/17/1937759.html
《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)...相关推荐
- ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)
视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...
- ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析
视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...
- 信息学奥赛真题解析(玩具谜题)
玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...
- 信息学奥赛之初赛 第1轮 讲解(01-08课)
信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...
- 信息学奥赛一本通习题答案(五)
最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...
- 信息学奥赛一本通习题答案(三)
最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...
- 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题
第1章 快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章 素数 第 3 章 约数 第 4 章 同余问题 第 5 章 矩阵乘法 第 6 章 ...
- 信息学奥赛一本通题目代码(非题库)
为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...
- 信息学奥赛一本通(C++版) 刷题 记录
总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...
- 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离
首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...
最新文章
- Android开发究竟该如何学习,含泪整理面经
- 17、uwp 打包失败记录
- pythonweb框架Flask学习笔记05-简单登陆
- Jenkins系统上的时间不正确问题
- Angular如何响应DOM event
- javaweb应用开发与实践pdf_基于阿里云打造「云原生」Web应用——「懒猪行」Web应用开发实践...
- QT出现“undefined reference to `vtable for’”解决方法
- win10远程桌面连接凭据怎么设置_想在家办公,只需打开win10远程桌面连接就可以了,还犹豫什么...
- DAN疼之后上些基础知识---自定义HttpModule和httpHandler
- cmd命令配置MySQL
- 汝跟被升职者之间,不存在竞争关系
- android gps 获取方位_Android GPS定位 获取经纬度
- FastReport 2021版中文手册PDF下载
- 短视频制作难度大吗?怎么剪辑短视频?
- 怎么获得MIUI12系统的root权限
- 书中自有黄金屋系列4:读《一课经济学》
- 在KVM虚拟化云主机上使用WXPE的研究
- Python“Non-ASCII character 'xe5' in file”报错问题
- 用Python写一个拼音输入法
- 计算机软件选修课选什么好,互联网行业,软件工程专业学什么?
热门文章
- intellij出现dependency ‘xxx‘not found
- 基于指数平滑对心电信号进行PQRST模拟(第二种方案)
- neo4j安装和启动
- Pessimistic Error Pruning example of C4.5
- 根据数据集获取概率密度图像和概率分布图像
- python:else与循环语句联合用法
- 【机器学习】传统目标检测算法总结
- tomcat jar包_tomcat学习|tomcat中的类加载器
- 在java.library.path中找不到允许在生产环境中实现最佳性能的基于APR的Apache Tom.....
- Disruptor并发框架--学习笔记