`
yesjavame
  • 浏览: 654398 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

LDT测试,在原来的基础上增加一个新的LDT,并在其下增加两个描述符测试LDT间和LDT内的跳转。

阅读更多

; ==========================================
; pmtest3.asm
; 编译方法:nasm pmtest3.asm -o pmtest3.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_DATA: Descriptor 0, DataLen - 1, DA_DRW+DA_DPL1 ; Data
LABEL_DESC_LDT1: Descriptor 0, LDTLen1 - 1, DA_LDT ; LDT1
LABEL_DESC_LDT2: Descriptor 0, LDTLen2 - 1, DA_LDT ; LDT1
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
SelectorLDT1 equ LABEL_DESC_LDT1 - LABEL_GDT
SelectorLDT2 equ LABEL_DESC_LDT2 - 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 - $$
DataLen equ $ - LABEL_DATA
; END of [SECTION .data1]



[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

; 初始化数据段描述符
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

; 初始化 LDT1 在 GDT 中的描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_LDT1
mov word [LABEL_DESC_LDT1 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_LDT1 + 4], al
mov byte [LABEL_DESC_LDT1 + 7], ah

; 初始化 LDT2 在 GDT 中的描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_LDT2
mov word [LABEL_DESC_LDT2 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_LDT2 + 4], al
mov byte [LABEL_DESC_LDT2 + 7], ah


; 初始化 LDT1 中的描述符A
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_CODE_A
mov word [LABEL_LDT1_DESC_CODEA + 2], ax
shr eax, 16
mov byte [LABEL_LDT1_DESC_CODEA + 4], al
mov byte [LABEL_LDT1_DESC_CODEA + 7], ah


; 初始化 LDT2 中的描述符B
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_CODE_B
mov word [LABEL_LDT2_DESC_CODEB + 2], ax
shr eax, 16
mov byte [LABEL_LDT2_DESC_CODEB + 4], al
mov byte [LABEL_LDT2_DESC_CODEB + 7], ah

; 初始化 LDT2 中的描述符C
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_CODE_C
mov word [LABEL_LDT2_DESC_CODEC + 2], ax
shr eax, 16
mov byte [LABEL_LDT2_DESC_CODEC + 4], al
mov byte [LABEL_LDT2_DESC_CODEC + 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, ax

mov 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 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: ; 显示完毕

; Load LDT
mov ax, SelectorLDT1
lldt ax

jmp SelectorLDT1CodeA:0 ; 跳入局部任务


SegCode32Len equ $ - LABEL_SEG_CODE32
; END of [SECTION .s32]


; 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, ax

mov eax, cr0
and al, 11111110b
mov cr0, eax

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

Code16Len equ $ - LABEL_SEG_CODE16

; END of [SECTION .s16code]


; LDT1
[SECTION .ldt1]
ALIGN 32
LABEL_LDT1:
LABEL_LDT1_DESC_CODEA: Descriptor 0, CodeALen - 1, DA_C + DA_32 ; Code, 32 位
LDTLen1 equ $ - LABEL_LDT1
SelectorLDT1CodeA equ LABEL_LDT1_DESC_CODEA - LABEL_LDT1 + SA_TIL
; END of [SECTION .ldt1]


; LDT2
[SECTION .ldt2]
ALIGN 32
LABEL_LDT2:
LABEL_LDT2_DESC_CODEB: Descriptor 0, CodeBLen - 1, DA_C + DA_32 ; Code, 32 位
LABEL_LDT2_DESC_CODEC: Descriptor 0, CodeCLen - 1, DA_C + DA_32 ; Code, 32 位
LDTLen2 equ $ - LABEL_LDT2
SelectorLDT2CodeB equ LABEL_LDT2_DESC_CODEB - LABEL_LDT2 + SA_TIL
SelectorLDT2CodeC equ LABEL_LDT2_DESC_CODEC - LABEL_LDT2 + SA_TIL
; END of [SECTION .ldt2]


; CodeA (LDT, 32 位代码段)
[SECTION .la]
ALIGN 32
[BITS 32]
LABEL_CODE_A:
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子(目的)

mov edi, (80 * 12 + 0) * 2 ; 屏幕第 10 行, 第 0 列。
mov ah, 0Ch ; 0000: 黑底 1100: 红字
mov al, 'A'
mov [gs:edi], ax

mov ax,SelectorLDT2
lldt ax
jmp SelectorLDT2CodeB:0 ;跳转到不同的LDT中,要先加载目标LDT


CodeALen equ $ - LABEL_CODE_A
; END of [SECTION .la]


; CodeB (LDT, 32 位代码段)
[SECTION .lb]
ALIGN 32
[BITS 32]
LABEL_CODE_B:
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子(目的)

mov edi, (80 * 12 + 4) * 2 ; 屏幕第 10 行, 第 4 列。
mov ah, 0Ch ; 0000: 黑底 1100: 红字
mov al, 'B'
mov [gs:edi], ax

jmp SelectorLDT2CodeC:0 ;同一LDT中不同段的可以直接跳转。
CodeBLen equ $ - LABEL_CODE_B
; END of [SECTION .lb]

; CodeC (LDT, 32 位代码段)
[SECTION .lc]
ALIGN 32
[BITS 32]
LABEL_CODE_C:
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子(目的)

mov edi, (80 * 12 + 8) * 2 ; 屏幕第 10 行, 第 8列。
mov ah, 0Ch ; 0000: 黑底 1100: 红字
mov al, 'C'
mov [gs:edi], ax

; 准备经由16位代码段跳回实模式
jmp SelectorCode16:0
CodeCLen equ $ - LABEL_CODE_C
; END of [SECTION .lc]

分享到:
评论

相关推荐

    微机课后题目答案 答案

    答:80386响应中断后,接收由中断源提供的类型码并将其乘8,与IDTR寄存器中基地址相加,指出中断描述符的位置,读出中断描述符,依其中的段选择符及条件决定从两个描述符表LDT或GDT中的一个得到段描述符,形成中断...

    Orange’s:一个操作系统的实现 Descriptor 3宏详解

     GDT/LDT:GDT/LDT是段描述符表,里面定义了每个段的段描述符的界限和属性,而段描述符的基址是在代码段中初始化的。  其中,LDT是局部描述符表,LDT在GDT中也有段描述符,LDT还有其对应的选择子,除此以外,LDT的...

    自己动手写操作系统(含源代码).part2

    上篇基本上是第一版的修订,只是做了一个调整,那便是在兼顾 Windows和Linux两方面用户的基础上,默认在Linux下建立开发环境来编写我们的操作系统。至于这样做的原因,在本书第 2章有比较详细的说明。当然,开发环境...

    自己动手写操作系统(含源代码).part1

    上篇基本上是第一版的修订,只是做了一个调整,那便是在兼顾 Windows和Linux两方面用户的基础上,默认在Linux下建立开发环境来编写我们的操作系统。至于这样做的原因,在本书第 2章有比较详细的说明。当然,开发环境...

    自己动手写操作系统 pdf

    自己动手写操作系统在详细分析操作系统原理的基础上,用丰富的实例代码,一步一步地指导读者用C语言和汇编语言编写出一个具备操作系统基本功能的操作系统框架。本书不同于其他的理论型书籍,而是提供给读者一个动手...

    自己动手写操作系统

    本书在详细分析操作系统原理的基础上,用丰富的实例代码,一步一步地指导读者用C语言和汇编语言编写出一个具备操作系统基本功能的操作系统框架。本书不同于其他的理论型书籍,而是提供给读者一个动手实践的路线图。...

    Linux0.11内核main函数那些事

    包括全局描述符表中的TSS0描述符和LDT0描述符的创建过程。与引导过程中全局描述符表及局部描述符表的创建过程构成了一个有机的知识块。在任务0从内核态切换到用户态过程中,可以学习到内核态堆栈与用户态堆栈概念...

    x86 x64体系探索及编程part3

    169 10.5.1 Segment Selector(段选择子) 169 10.5.2 Descriptor Table(描述符表) 172 10.5.3 Segment Selector Register(段寄存器) 174 10.5.4 Segment Descriptor(段描述符) 175 10.5.5 LDT 描述符与LDT ...

    自己动手写操作系统 电子工业出版社 pdf

    第1章 马上动手写一个最小的“操作系统”1 1.1 准备工作1 1.2 10分钟完成的操作系统1 1.3 Boot Sector3 1.4 代码解释3 1.5 水面下的冰山5 1.6 回顾6 第2章 搭建你的工作环境7 2.1 虚拟计算机(Virtual PC)7 2.1.1 ...

    x86 x64体系探索及编程part4

    169 10.5.1 Segment Selector(段选择子) 169 10.5.2 Descriptor Table(描述符表) 172 10.5.3 Segment Selector Register(段寄存器) 174 10.5.4 Segment Descriptor(段描述符) 175 10.5.5 LDT 描述符与LDT ...

    x86 x64体系探索及编程 part2

    169 10.5.1 Segment Selector(段选择子) 169 10.5.2 Descriptor Table(描述符表) 172 10.5.3 Segment Selector Register(段寄存器) 174 10.5.4 Segment Descriptor(段描述符) 175 10.5.5 LDT 描述符与LDT ...

    x86 x64体系探索及编程part1

    169 10.5.1 Segment Selector(段选择子) 169 10.5.2 Descriptor Table(描述符表) 172 10.5.3 Segment Selector Register(段寄存器) 174 10.5.4 Segment Descriptor(段描述符) 175 10.5.5 LDT 描述符与LDT ...

    问题清单解答(来源不明)1

    1. 什么是实模式,什么是保护模式 2. 什么是选择子 3. 什么是描述符 4. 什么是 GDT,什么是 LDT 5. 请分别说明 GDTR 和 LDTR 的结

Global site tag (gtag.js) - Google Analytics