⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 汇编006.txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
  BASE32 DD 0
  LIMIT16 DW 0
  PreDesc ENDS
局部描述表寄存器LDTR规定了当前任中使用的局部描述表LDT,LDTR类似于一个段寄存,它的长度为32位,一个16位的寄存器和对程序员来讲不可见的高速缓冲存储器。每一个任务的局部描述符表作为一个特殊的系统段,它由定义在全局描述符表GDT中的描述符来描述,前面已提到过一个任务只能有一张全局描述符表GDT和一张中断描述符表IDT,但可以有多张局部描述行表LDT,而每一张局部描述符表都由定义在GDT中的描述符来确定。通常将描述LDT的选择子装入到LDTR,LDTR根据选择子从全局描述符表中取出对应的描述符,并把LDT的基址及界限信息保存到对程序员来讲不可见的高速缓冲存储器,随后就可以对LDT进行访问。当前任务中的所有段都由GDT中的描述符来描述。
   _________       ____________________________________________________
   |       |______|                   |                     |         |
   | LDTR  |______| 32位基址          | 32位界限            |12位属性 |
   |_______|      |___________________|_____________________|_________|

中断描述符表和全局描述符表一样,长度为48位。32位段基址和16位界限。
如何从实式模式切换到保护模式下呢?通常来讲,要两个步骤:1.作好切换到保护模式下的准备;2.切换到保护模式。主要准备工作就是建立全局描述符表,并使GDTR指向GDT,因为切换到保护模式下,至少要将代码段的选择子装入到CS中,看程序片段:

;定义好描述符的结构
DESCRIPTOR STRUCT
  LIMIT DW 0;段界限
  BASEL DW 0;段基址的低16位
  BASEM DB 0;段基址的16~23位
  ATTRIBUTES DW 0;段属性
  BASEH DB 0;段基址的高8位,24~31
DESCRIPTOR ENDS
;定义好伪描述符
PDESC STRUCT
  LIMIT DW 0
  BASE DD 0
PDESC ENDS
;通常要定义一个段间跳转的宏,这样的话就可以保证在进入保护模式时将代码段的选择子装入到CS寄存器
JUMP MACRO selector,offset
  DB 0EAH
  DW offsetv;段偏移
  DW selector;段选择子
  ENDM
;打开A20地址线
PUSH AX
IN AL,92H
OR AL,2
OUT 92H,AL
POP AX
;关闭A20地址线
PUSH AX
IN AL,92H
AND AL,0FDH
OUT 92H,AL
POP AX
;切换到保护模式下,将CR0寄存中的第0位置1
MOV EAX,CR0
OR CR0,1
MOV CR0,EAX
其它的部分就要根据具体的应用来写, 下面的例子是如何在保护模下访问820000H单元开始的内容,看程序:
.386P
data segment use16
GDT LABEL BYTE;定义全局描述符表
DUMMY DESCRIPTOR<>;空描述符,它有特定义的含义,空描述符可以保证GDT中的第1个描述符永远不会被访问
CODE DESCRIPTOR<0FFFFH,,,SAttr,>;代码段的描述符
CODE_SEL=CODE-GDT;代码段描述符的选择子
DATAS DESCRIPTOR<0FFFFH,0H,82H,DAttr,>;源数据段描述符,即820000H
DATAS_SEL=DATAS-GDT;源数据段选择子
GDTLEN=$-GDT
VGDTR DESCRIPTOR<GDTLEN-1,>
data ends

code segment use16
   assume cs:code,ds:data
start:
   mov ax,data
   mov ds,ax
   mov bx,16
   mul bx;设置全局描述表GDT基址,因为现在还处在实模式下,所以段地址要左移4位
   add ax,offset GDT
   adc dx,0
   mov word ptr VGDTR.BASE,ax;设置全局描述符表寄存器GDTR的内容
   mov word ptr VGDTR.BASE+2,dx
   ;设置代码段描述符
   mov ax,cs
   mul bx
   mov CODE.BASEL,ax
   mov CODE.BASEM,dl
   mov CODE.BASEH,dh      
   ;以下部分你可以根据实际的应用来编写
   .........
   ...........
   ;加载GDTR
   LGDT QWORD PTR VGDTR
   CLI;关中断
   ;打开A20地址线
   ;切换到保护模式
   mov eax,cr0
   or eax,1
   mov cr0,eax
   JUMP <CODE_SEL>,<OFFSET VIRTUAL>;清指令预取队列,真正进入保护模式
   ........
   ........
   virutal:
     ;add your code here according to your needs
   ............
   ;回到实模式
   ;关闭A20地址线
   STI;开中断
code ends
end start
上述的程序片段是随手写的,可根据需要自已加以调整,不过有点要说明。
a.通常来讲,从实模式下切换到保护模式下只要将CR0寄存器中的最低位设置为1就可以了。但是,此时CS的内容仍然是实模式下的内容,所以加了一条段间跳转指令JUMP <CODE_SEL>,<OFFSET VIRTUAL>,执行完这条指令就可以将代码段选择子CODE_SEL装入到段寄存器CS中,同时也可以刷新指令预取队列。  
b.LGDT QWORD PTR VGDTR,该指令的功能是将VGDTR的内容装入到全局描述符表寄存器GDTR中。
c.上面的代码片段中并没有建立中断描述符表IDT,这样的话就要求整个程序必须运行在关中断情况下进行。
d.为了访问1M以上的存储单元,应该打开A20地址线,在WINDOWS下只需加载HIMEM.SYS就可以了。能不能进入保护模式只与是否加载HIMEM.SYS有关,与处理器工作在实方式下还是在保护方式下无关。也就是说,只要加载HIMEM.SYS,就算处理器当前处在实模式下,A20地址线关闭,处理器也一样可以进入保护模式。
下集预告:
80386ASM程序设计基础(十二)---任务切换
80386ASM程序设计基础(十三)---80386中断和异常
80386ASM程序设计基础(十四)---分页管理机制
80386ASM程序设计基础(十五)---V86模式
敬请关注,谢谢。   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -