首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 操作系统 >

(第三章 八)通过调用门进行有特权级变换的转移(一)

2012-07-15 
(第三章 8)通过调用门进行有特权级变换的转移(一)下面代码中,和TSS相关用红色标记;调用门本身用深绿色标记

(第三章 8)通过调用门进行有特权级变换的转移(一)

下面代码中,

和TSS相关用红色标记;

调用门本身用深绿色标记;

调用门指向的段用浅绿色标记;

?

; ==========================================

; pmtest5.asm

; 编译方法:nasm pmtest5.asm -o pmtest5.com

; ==========================================

?

%include"pm.inc"; 常量, 宏, 以及一些说明

?

org0100h

jmpLABEL_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_CODE_RING3: Descriptor 0, SegCodeRing3Len-1, DA_C+DA_32+DA_DPL3

LABEL_DESC_DATA: ? ? ? Descriptor 0, ? ? DataLen-1, DA_DRW ? ? ? ? ? ? ;Data

LABEL_DESC_STACK: ? ? ?Descriptor 0, ? ? ? ?TopOfStack, DA_DRWA+DA_32 ? ;Stack,32

LABEL_DESC_STACK3: ? ? Descriptor 0, ? ? ? TopOfStack3, DA_DRWA+DA_32+DA_DPL3

LABEL_DESC_LDT: ? ? ? ?Descriptor 0, ? ? ? ? ?LDTLen-1, DA_LDT ? ;LDT

LABEL_DESC_TSS: ? ? ? ?Descriptor 0, ? ? ? ? ?TSSLen-1, DA_386TSS ? ;TSS

LABEL_DESC_VIDEO: ? ? ?Descriptor 0B8000h, ? ? ?0ffffh, DA_DRW+DA_DPL3

?

; 门 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?目标选择子, ? ? ? 偏移, DCount, 属性

LABEL_CALL_GATE_TEST:Gate ?SelectorCodeDest, ? ? ? ? ?0, ? ? ?0, DA_386CGate + DA_DPL3

; GDT 结束

?

GdtLenequ$ - LABEL_GDT; GDT长度

GdtPtrdwGdtLen - 1; GDT界限

dd0; GDT基地址

?

; GDT 选择子

SelectorNormalequLABEL_DESC_NORMAL- LABEL_GDT

SelectorCode32equLABEL_DESC_CODE32- LABEL_GDT

SelectorCode16equLABEL_DESC_CODE16- LABEL_GDT

SelectorCodeDestequLABEL_DESC_CODE_DEST- LABEL_GDT

SelectorCodeRing3equLABEL_DESC_CODE_RING3- LABEL_GDT + SA_RPL3

SelectorDataequLABEL_DESC_DATA- LABEL_GDT

SelectorStackequLABEL_DESC_STACK- LABEL_GDT

SelectorStack3equLABEL_DESC_STACK3- LABEL_GDT + SA_RPL3

SelectorLDTequLABEL_DESC_LDT- LABEL_GDT

SelectorTSSequLABEL_DESC_TSS- LABEL_GDT

SelectorVideoequLABEL_DESC_VIDEO- LABEL_GDT

?

SelectorCallGateTestequLABEL_CALL_GATE_TEST- LABEL_GDT + SA_RPL3

; END of [SECTION .gdt]

?

[SECTION .data1] ; 数据段

ALIGN32

[BITS32]

LABEL_DATA:

SPValueInRealModedw0

; 字符串

PMMessage:db"In Protect Mode now. ^-^", 0; 进入保护模式后显示此字符串

OffsetPMMessageequPMMessage - $$

StrTest:db"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0

OffsetStrTestequStrTest - $$

DataLenequ$ - LABEL_DATA

; END of [SECTION .data1]

?

?

; 全局堆栈段

[SECTION .gs]

ALIGN32

[BITS32]

LABEL_STACK:

times 512 db 0

TopOfStackequ$ - LABEL_STACK - 1

; END of [SECTION .gs]

?

?

; 堆栈段ring3

[SECTION .s3]

ALIGN32

[BITS32]

LABEL_STACK3:

times 512 db 0

TopOfStack3equ$ - LABEL_STACK3 - 1

; END of [SECTION .s3]

?

?

; TSS ---------------------------------------------------------

[SECTION .tss]

ALIGN32

[BITS32]

LABEL_TSS:

DD0; Back

DDTopOfStack; 0 级堆栈 -->除了0级堆栈外,其他字段没做任何初始化。因为本例中只用到这部分

DDSelectorStack; ? ? ? ? -->除了0级堆栈外,其他字段没做任何初始化。因为本例中只用到这部分

?

DD0; 1 级堆栈

DD0;?

DD0; 2 级堆栈

DD0;?

DD0; CR3

DD0; EIP

DD0; EFLAGS

DD0; EAX

DD0; ECX

DD0; EDX

DD0; EBX

DD0; ESP

DD0; EBP

DD0; ESI

DD0; EDI

DD0; ES

DD0; CS

DD0; SS

DD0; DS

DD0; FS

DD0; GS

DD0; LDT

DW0; 调试陷阱标志

DW$ - LABEL_TSS + 2; I/O位图基址

DB0ffh; I/O位图结束标志

TSSLenequ$ - LABEL_TSS

; TSS ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

?

?

[SECTION .s16]

[BITS16]

LABEL_BEGIN:

movax, cs

movds, ax

moves, ax

movss, ax

movsp, 0100h

?

mov[LABEL_GO_BACK_TO_REAL+3], ax

mov[SPValueInRealMode], sp

?

; 初始化 16 位代码段描述符

movax, cs

movzxeax, ax

shleax, 4

addeax, LABEL_SEG_CODE16

movword [LABEL_DESC_CODE16 + 2], ax

shreax, 16

movbyte [LABEL_DESC_CODE16 + 4], al

movbyte [LABEL_DESC_CODE16 + 7], ah

?

; 初始化 32 位代码段描述符

xoreax, eax

movax, cs

shleax, 4

addeax, LABEL_SEG_CODE32

movword [LABEL_DESC_CODE32 + 2], ax

shreax, 16

movbyte [LABEL_DESC_CODE32 + 4], al

movbyte [LABEL_DESC_CODE32 + 7], ah

?

; 初始化测试调用门的代码段描述符

xoreax, eax

movax, cs

shleax, 4

addeax, LABEL_SEG_CODE_DEST

movword [LABEL_DESC_CODE_DEST + 2], ax

shreax, 16

movbyte [LABEL_DESC_CODE_DEST + 4], al

movbyte [LABEL_DESC_CODE_DEST + 7], ah

?

; 初始化数据段描述符

xoreax, eax

movax, ds

shleax, 4

addeax, LABEL_DATA

movword [LABEL_DESC_DATA + 2], ax

shreax, 16

movbyte [LABEL_DESC_DATA + 4], al

movbyte [LABEL_DESC_DATA + 7], ah

?

; 初始化堆栈段描述符

xoreax, eax

movax, ds

shleax, 4

addeax, LABEL_STACK

movword [LABEL_DESC_STACK + 2], ax

shreax, 16

movbyte [LABEL_DESC_STACK + 4], al

movbyte [LABEL_DESC_STACK + 7], ah

?

; 初始化堆栈段描述符(ring3)

xoreax, eax

movax, ds

shleax, 4

addeax, LABEL_STACK3

movword [LABEL_DESC_STACK3 + 2], ax

shreax, 16

movbyte [LABEL_DESC_STACK3 + 4], al

movbyte [LABEL_DESC_STACK3 + 7], ah

?

; 初始化 LDT 在 GDT 中的描述符

xoreax, eax

movax, ds

shleax, 4

addeax, LABEL_LDT

movword [LABEL_DESC_LDT + 2], ax

shreax, 16

movbyte [LABEL_DESC_LDT + 4], al

movbyte [LABEL_DESC_LDT + 7], ah

?

; 初始化 LDT 中的描述符

xoreax, eax

movax, ds

shleax, 4

addeax, LABEL_CODE_A

movword [LABEL_LDT_DESC_CODEA + 2], ax

shreax, 16

movbyte [LABEL_LDT_DESC_CODEA + 4], al

movbyte [LABEL_LDT_DESC_CODEA + 7], ah

?

; 初始化Ring3描述符

xoreax, eax

movax, ds

shleax, 4

addeax, LABEL_CODE_RING3

movword [LABEL_DESC_CODE_RING3 + 2], ax

shreax, 16

movbyte [LABEL_DESC_CODE_RING3 + 4], al

movbyte [LABEL_DESC_CODE_RING3 + 7], ah

?

; 初始化 TSS 描述符

xoreax, eax

movax, ds

shleax, 4

addeax, LABEL_TSS

movword [LABEL_DESC_TSS + 2], ax

shreax, 16

movbyte [LABEL_DESC_TSS + 4], al

movbyte [LABEL_DESC_TSS + 7], ah

?

; 为加载 GDTR 作准备

xoreax, eax

movax, ds

shleax, 4

addeax, LABEL_GDT; eax <- gdt 基地址

movdword [GdtPtr + 2], eax; [GdtPtr + 2] <- gdt 基地址

?

; 加载 GDTR

lgdt[GdtPtr]

?

; 关中断

cli

?

; 打开地址线A20

inal, 92h

oral, 00000010b

out92h, al

?

; 准备切换到保护模式

moveax, cr0

oreax, 1

movcr0, eax

?

; 真正进入保护模式

jmpdword SelectorCode32:0; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0 ?处

?

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

?

LABEL_REAL_ENTRY:; 从保护模式跳回到实模式就到了这里

movax, cs

movds, ax

moves, ax

movss, ax

?

movsp, [SPValueInRealMode]

?

inal, 92h; ┓

andal, 11111101b; ┣ 关闭 A20 地址线

out92h, al; ┛

?

sti; 开中断

?

movax, 4c00h; ┓

int21h; ┛回到 DOS

; END of [SECTION .s16]

?

?

[SECTION .s32]; 32 位代码段. 由实模式跳入.

[BITS32]

?

LABEL_SEG_CODE32:

movax, SelectorData

movds, ax; 数据段选择子

movax, SelectorVideo

movgs, ax; 视频段选择子

?

movax, SelectorStack

movss, ax; 堆栈段选择子

?

movesp, TopOfStack

?

?

; 下面显示一个字符串

movah, 0Ch; 0000: 黑底 ? ?1100: 红字

xoresi, esi

xoredi, edi

movesi, OffsetPMMessage; 源数据偏移

movedi, (80 * 10 + 0) * 2; 目的数据偏移。屏幕第 10 行, 第 0 列。

cld

.1:

lodsb

testal, al

jz.2

mov[gs:edi], ax

addedi, 2

jmp.1

.2:; 显示完毕

?

callDispReturn

?

; Load TSS

movax, SelectorTSS

ltrax; 在任务内发生特权级变换时要切换堆栈,而内层(高特权级)堆栈的指针存放在当前任务的TSS中,所以要设置任务状态段寄存器TR。

?

pushSelectorStack3

pushTopOfStack3

pushSelectorCodeRing3

push0

retf; Ring0 -> Ring3,历史性转移!将打印数字 '3'。

?

; ------------------------------------

DispReturn:

pusheax

pushebx

moveax, edi

movbl, 160

divbl

andeax, 0FFh

inceax

movbl, 160

mulbl

movedi, eax

popebx

popeax

?

ret

; DispReturn 结束---------------------

?

SegCode32Lenequ$ - LABEL_SEG_CODE32

; END of [SECTION .s32]

?

?

[SECTION .sdest]; 调用门目标段

[BITS32]


LABEL_SEG_CODE_DEST:

movax, SelectorVideo

movgs, ax; 视频段选择子(目的)


movedi, (80 * 12 + 0) * 2; 屏幕第 12 行, 第 0 列。

movah, 0Ch; 0000: 黑底 ? ?1100: 红字

moval, 'C'

mov[gs:edi], ax


; Load LDT

movax, SelectorLDT

lldtax


jmpSelectorLDTCodeA:0; 跳入局部任务,将打印字母 'L'。


;retf


SegCodeDestLenequ$ - LABEL_SEG_CODE_DEST

; END of [SECTION .sdest]

?

?

; 16 位代码段. 由 32 位代码段跳入, 跳出后到实模式

[SECTION .s16code]

ALIGN32

[BITS16]

LABEL_SEG_CODE16:

; 跳回实模式:

movax, SelectorNormal

movds, ax

moves, ax

movfs, ax

movgs, ax

movss, ax

?

moveax, cr0

andal, 11111110b

movcr0, eax

?

LABEL_GO_BACK_TO_REAL:

jmp0:LABEL_REAL_ENTRY; 段地址会在程序开始处被设置成正确的值

?

Code16Lenequ$ - LABEL_SEG_CODE16

?

; END of [SECTION .s16code]

?

?

; LDT

[SECTION .ldt]

ALIGN32

LABEL_LDT:

; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 段基址 ? ? ? 段界限 ? ? , ? 属性

LABEL_LDT_DESC_CODEA:Descriptor ? ? ? 0, ? ? CodeALen - 1, ? DA_C + DA_32; Code, 32 位

?

LDTLenequ$ - LABEL_LDT

?

; LDT 选择子

SelectorLDTCodeAequLABEL_LDT_DESC_CODEA- LABEL_LDT + SA_TIL

; END of [SECTION .ldt]

?

?

; CodeA (LDT, 32 位代码段)

[SECTION .la]

ALIGN32

[BITS32]

LABEL_CODE_A:

movax, SelectorVideo

movgs, ax; 视频段选择子(目的)

?

movedi, (80 * 13 + 0) * 2; 屏幕第 13 行, 第 0 列。

movah, 0Ch; 0000: 黑底 ? ?1100: 红字

moval, 'L'

mov[gs:edi], ax

?

; 准备经由16位代码段跳回实模式

jmpSelectorCode16:0

CodeALenequ$ - LABEL_CODE_A

; END of [SECTION .la]

?

?

; CodeRing3

[SECTION .ring3]

ALIGN32

[BITS32]

LABEL_CODE_RING3:

movax, SelectorVideo

movgs, ax; 视频段选择子(目的)

?

movedi, (80 * 14 + 0) * 2; 屏幕第 14 行, 第 0 列。

movah, 0Ch; 0000: 黑底 ? ?1100: 红字

moval, '3'

mov[gs:edi], ax

?

callSelectorCallGateTest:0; 测试调用门(有特权级变换),将打印字母 'C'。

jmp$

SegCodeRing3Lenequ$ - LABEL_CODE_RING3

; END of [SECTION .ring3]

热点排行