+ -
当前位置:首页 → 问答吧 → 请问:LDT的问题

请问:LDT的问题

时间:2011-01-10

来源:互联网

请看:如果我把这两句注释掉,仍然可以运行,难道LDT不装载也可以吗?
MOV AX,LDT_SEL
LLDT AX  

以下是源代码:
   
;16位偏移的段间转移宏指令
JUMP16 MACRO selector, offsetv
  DB 0EAH ;操作码
  DW offsetv ;16位偏移
  DW selector ;段值/选择子
  ENDM
;存储段描述符/系统段描述符结构类型的定义
DESCRIPTOR STRUC
  LIMITL DW 0 ;段界限(0~15)
  BASEL DW 0 ;段基地址(0~15)
  BASEM DB 0 ;段基地址(16~23)
  ATTRIBUTES DW 0 ;段属性
  BASEH DB 0 ;段基地址(24~31)
DESCRIPTOR ENDS

;--------------------------------------------------------
;伪描述符结构类型的定义
PDESC STRUC
  LIMIT DW 0 ;GDT的大小,以字节为单位
  BASE DD 0 ;GDT的基地址
PDESC ends

  .386P
;=========GDT
GDTSEG SEGMENT PARA USE16  
GDT LABEL BYTE
DUMMY DESCRIPTOR <> ;空结构  
;global segment
CODEK DESCRIPTOR <0FFFFH,,,98H,>  
CODEK_SEL = CODEK - GDT
;local segment
LDTABLE DESCRIPTOR <0FFFFH,,,82H,>  
LDT_SEL = LDTABLE - GDT
GDTLEN = $ - GDT  
GDTSEG ENDS
;============实方式数据段
RDATASEG SEGMENT PARA USE16
VGDTR PDESC <GDTLEN-1,> ;GDT伪描述符
RDATASEG ENDS
;=============LDT
LDTSEG SEGMENT PARA USE16  
LDT LABEL BYTE 
;注意LDT没有空结构
CODEL DESCRIPTOR <0FFFFH,,,98H,>  
CODEL_SEL = (CODEL-LDT) + 04H ;局部段选择子
LDTLEN = $ - LDT  
LDTSEG ENDS

;演示任务代码段L,是局部代码段
CODELSEG SEGMENT PARA USE16  
  ASSUME CS:CODELSEG
VIRTUAL2:
  ;
  JUMP16 CODEK_SEL,VIRTUAL3 ;跳转到代码段K
CODELLEN = $ - VIRTUAL2 ;CODELSEG
CODELSEG ENDS
;-----------------------------------------------------
;演示任务代码段K,是全局代码段
CODEKSEG SEGMENT PARA USE16  
  ASSUME CS:CODEKSEG
VIRTUAL1:
  ;我把这两句注释掉,仍然可以运行,为什么?
  MOV AX,LDT_SEL
  LLDT AX ;装载局部描述符表寄存器LDTR
  ;
  JUMP16 CODEL_SEL,VIRTUAL2 ;跳转到局部代码段L
VIRTUAL3:
  ;
  MOV EAX,CR0
  AND EAX,0FFFFFFFEH
  MOV CR0,EAX ;返回实方式
  JUMP16 <SEG REAL>,<OFFSET REAL>
CODEKSEG ENDS
;=============开始程序,代码段
RECODESEG SEGMENT PARA USE16
  ASSUME CS:RECODESEG
START:  
  ASSUME DS:GDTSEG ;GDT的数据定义段
  MOV AX,GDTSEG
  MOV DS,AX
  ;初始化全局描述符表(两个描述符)
  MOV BX,16
  MOV AX,CODEKSEG ;全局代码段,段开始的偏移地址都是为0
  MUL BX
  MOV CODEK.BASEL,AX
  MOV CODEK.BASEM,DL
  MOV CODEK.BASEH,DH
;
  MOV AX,LDTSEG ;局部描述符表
  MUL BX
  MOV LDTABLE.BASEL,AX
  MOV LDTABLE.BASEM,DL
  MOV LDTABLE.BASEH,DH
  ;初始化演示任务LDT
ASSUME DS:LDTSEG
  MOV AX,LDTSEG
  MOV DS,AX
  MOV BX,16
  MOV AX,CODELSEG ;局部代码段
  MUL BX
  MOV CODEL.BASEL,AX
  MOV CODEL.BASEM,DL
  MOV CODEL.BASEH,DH
;装载GDTR
ASSUME DS:RDATASEG
  MOV AX,RDATASEG
  MOV DS,AX
  MOV AX,GDTSEG
  MUL BX
  MOV WORD PTR VGDTR.BASE,AX
  MOV WORD PTR VGDTR.BASE+2,DX
  LGDT FWORD PTR VGDTR
  CLI
  ;切换到保护方式
call ea20  
  MOV EAX,CR0
  OR EAX,1
  MOV CR0,EAX
  JUMP16 <CODEK_SEL>,<OFFSET VIRTUAL1>


  REAL:;又回到实方式
call da20 ;关闭地址线A20
sti ;开中断

MOV AX,4C00H
  INT 21H
;打开地址线A20
ea20 proc
  push ax
  in al,92h
  or al,2
  out 92h,al
  pop ax
  ret
ea20 endp
;
;关闭地址线A20
da20 proc
  push ax
  in al,92h
  and al,0fdh ;0fdh=not 20h
  out 92h,al
  pop ax
  ret
da20 endp
;
   
RECODESEG ENDS
  END START

作者: leetow2003   发布时间: 2011-01-10

LDT 是可选的,GDT 才是必须的。

作者: Michael_g   发布时间: 2011-01-10