《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)...
在上次的代碼基礎(chǔ)上,添加一個(gè)代碼段作為通過(guò)調(diào)用門轉(zhuǎn)移的目標(biāo)段。了解一下調(diào)用的工作方法,代碼分析如下:
<<紅色標(biāo)識(shí)部分為新增代碼>>
; ==========================================
; pmtest4.asm
; 編譯方法:nasm pmtest4.asm -o pmtest4.com
; ==========================================
%include??? "pm.inc"??? ; 常量, 宏, 以及一些說(shuō)明
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;目標(biāo)代碼描述符
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??? ; 顯存首地址
; 門?????????????????????????????? 目標(biāo)選擇子,偏移,DCount, 屬性
LABEL_CALL_GATE_TEST: Gate SelectorCodeDest,?? 0,???? 0, DA_386CGate+DA_DPL0;調(diào)用門描述符DPL=0
; GDT 結(jié)束
GdtLen??????? equ??? $ - LABEL_GDT??? ; GDT長(zhǎng)度
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;目標(biāo)代碼選擇子
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_GDT
SelectorCallGateTest??? equ??? LABEL_CALL_GATE_TEST??? - LABEL_GDT;調(diào)用門選擇子
; END of [SECTION .gdt]
[SECTION .data1]???? ; 數(shù)據(jù)段
ALIGN??? 32
[BITS??? 32]
LABEL_DATA:
SPValueInRealMode??? dw??? 0
; 字符串
PMMessage:??????? db??? "In Protect Mode now. ^-^", 0??? ; 進(jìn)入保護(hù)模式后顯示此字符串
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, cs
??? mov??? ds, ax
??? mov??? es, ax
??? mov??? ss, ax
??? mov??? sp, 0100h
??? mov??? [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
??? ; 初始化測(cè)試調(diào)用門的代碼段描述符
??? 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
??? ; 初始化數(shù)據(jù)段描述符
??? 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 作準(zhǔn)備
??? 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]
??? ; 關(guān)中斷
??? cli
??? ; 打開地址線A20
??? in??? al, 92h
??? or??? al, 00000010b
??? out??? 92h, al
??? ; 準(zhǔn)備切換到保護(hù)模式
??? mov??? eax, cr0
??? or??? eax, 1
??? mov??? cr0, eax
??? ; 真正進(jìn)入保護(hù)模式
??? jmp??? dword SelectorCode32:0??? ; 執(zhí)行這一句會(huì)把 SelectorCode32 裝入 cs, 并跳轉(zhuǎn)到 Code32Selector:0? 處
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LABEL_REAL_ENTRY:??????? ; 從保護(hù)模式跳回到實(shí)模式就到了這里
??? mov??? ax, cs
??? mov??? ds, ax
??? mov??? es, ax
??? mov??? ss, ax
??? mov??? sp, [SPValueInRealMode]
??? in??? al, 92h??????? ; ┓
??? and??? al, 11111101b??? ; ┣ 關(guān)閉 A20 地址線
??? out??? 92h, al??????? ; ┛
??? sti??????????? ; 開中斷
??? mov??? ax, 4c00h??? ; ┓
??? int??? 21h??????? ; ┛回到 DOS
; END of [SECTION .s16]
[SECTION .s32]; 32 位代碼段. 由實(shí)模式跳入.
[BITS??? 32]
LABEL_SEG_CODE32:
??? mov??? ax, SelectorData
??? mov??? ds, ax??????????? ; 數(shù)據(jù)段選擇子
??? mov??? ax, SelectorVideo
??? mov??? gs, ax??????????? ; 視頻段選擇子
??? mov??? ax, SelectorStack
??? mov??? ss, ax??????????? ; 堆棧段選擇子
??? mov??? esp, TopOfStack
??? ; 下面顯示一個(gè)字符串
??? mov??? ah, 0Ch??????????? ; 0000: 黑底??? 1100: 紅字
??? xor??? esi, esi
??? xor??? edi, edi
??? mov??? esi, OffsetPMMessage??? ; 源數(shù)據(jù)偏移
??? mov??? edi, (80 * 10 + 0) * 2??? ; 目的數(shù)據(jù)偏移。屏幕第 10 行, 第 0 列。
??? cld
.1:
??? lodsb
??? test??? al, al
??? jz??? .2
??? mov??? [gs:edi], ax
??? add??? edi, 2
??? jmp??? .1
.2:??? ; 顯示完畢
??? call??? DispReturn
??? ; 測(cè)試調(diào)用門(無(wú)特權(quán)級(jí)變換),將打印字母 'C'
??? call??? SelectorCallGateTest:0
??? ;call??? SelectorCodeDest:0 ---SelectorCallGateTest的選擇子為SelectorCodeDest,偏移為0
??? ; Load LDT
??? mov??? ax, SelectorLDT
??? lldt??? ax
??? jmp??? SelectorLDTCodeA:0??? ; 跳入局部任務(wù),將打印字母 '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??? eax
??? ret
; DispReturn 結(jié)束---------------------------------------------------------
SegCode32Len??? equ??? $ - LABEL_SEG_CODE32
; END of [SECTION .s32]
[SECTION .sdest]; 調(diào)用門目標(biāo)段
[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], ax
??? retf
SegCodeDestLen??? equ??? $ - LABEL_SEG_CODE_DEST
; END of [SECTION .sdest]
; 16 位代碼段. 由 32 位代碼段跳入, 跳出后到實(shí)模式
[SECTION .s16code]
ALIGN??? 32
[BITS??? 16]
LABEL_SEG_CODE16:
??? ; 跳回實(shí)模式:
??? mov??? ax, SelectorNormal
??? mov??? ds, ax
??? mov??? es, ax
??? mov??? fs, ax
??? mov??? gs, ax
??? mov??? ss, ax
??? mov??? eax, cr0
??? and??? al, 11111110b
??? mov??? cr0, eax
LABEL_GO_BACK_TO_REAL:
??? jmp??? 0:LABEL_REAL_ENTRY??? ; 段地址會(huì)在程序開始處被設(shè)置成正確的值
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
??? ; 準(zhǔn)備經(jīng)由16位代碼段跳回實(shí)模式
??? jmp??? SelectorCode16:0
CodeALen??? equ??? $ - LABEL_CODE_A
; END of [SECTION .la]
Gate宏的分析請(qǐng)見《Orange’s 一個(gè)操作系統(tǒng)的實(shí)現(xiàn)》3.保護(hù)模式1----pm.inc分析:
?
本代碼只是展示了調(diào)用的使用方式,即提供了目標(biāo)代碼段的入口地址及相關(guān)附加屬性(無(wú)特權(quán)級(jí)的轉(zhuǎn)移),如果需要特權(quán)級(jí)的轉(zhuǎn)移,則需
參照以下規(guī)則:
假設(shè)我們有代碼A轉(zhuǎn)移到代碼B,使用一個(gè)調(diào)用G,即調(diào)用門G中的目標(biāo)選擇子指向代碼B的段。我們涉及到這么幾個(gè)要素CPL、RPL、
代碼B的DPL(記做DPL_B)、調(diào)用門的DPL(記做DPL_G)。根據(jù)《Orange’s 一個(gè)操作系統(tǒng)的實(shí)現(xiàn)》3.保護(hù)模式5----特權(quán)級(jí)概述(轉(zhuǎn))
介紹可知A訪問(wèn)調(diào)用門G時(shí),相當(dāng)于訪問(wèn)一個(gè)數(shù)據(jù)段,要求CPL和RPL都小于或者等于DPL_G.換句話說(shuō),CPL和RPL須在更高的特權(quán)級(jí)上.
除此之外,還需比較CPL和DPL_B,如果是一致代碼段,則要求DPL_B<=CPL;如果是非一致代碼段,call和jmp指令又有所不同,使用
CALL時(shí),要求DPL_B<=CPL;使用Jmp時(shí),只能是DPL-B=CPL
規(guī)則如下
| 目標(biāo)代碼段 | call | jmp |
| 目標(biāo)是一致代碼段 | CPL<=DPL_G | 同CALL |
| ? | RPL<=DPL_G | 同CALL |
| ? | DPL_B<=CPL | 同CALL |
| 目標(biāo)是非一致代碼 | CPL<=DPL_G | CPL<=DPL_G |
| ? | RPL<=DPL_G | RPL<=DPL_G |
| ? | DPL_B<=CPL | DPL_B=CPL |
綜上:通過(guò)調(diào)用門和call指令,可以實(shí)現(xiàn)從低特權(quán)級(jí)到高特權(quán)級(jí)的轉(zhuǎn)移,無(wú)論目標(biāo)代碼是一致的還是非一致的
轉(zhuǎn)載于:https://www.cnblogs.com/Aoysme/archive/2011/01/17/1937759.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mac下IPhone开发环境配置
- 下一篇: Windows下删除.svn文件夹的简易