杨季文 80x86汇编语言程序设计 实例五

时间:2022-04-17 19:25:33

;编译:TASM T10-5.ASM
;链接:TLINK /32 T10-5.OBJ


INCLUDE 386SCD.asm
.386P

GDTSEG SEGMENT PARA USE16
    GDT     LABEL   BYTE
    DUMMY   DESCRIPTOR  <>
    NORMAL  DESCRIPTOR  <0FFFFH,0,0,92H,>
    NORMAL_SEL = NORMAL-GDT
    EFFGDT  LABEL   BYTE
    DEMOTSS DESCRIPTOR  <DEMOTSSLEN-1,DEMOTSSSEG,0,89H,>
    DEMOTSS_SEL = DEMOTSS-GDT
    DEMOLDTD DESCRIPTOR <DEMOLDTLEN-1,DEMOLDTSEG,,82H,>
    DEMOLDT_SEL = DEMOLDTD-GDT
    TEMPTSS  DESCRIPTOR <TEMPTSSLEN-1,TEMPTSSSEG,,89H+40H,>
    TEMPTSS_SEL = TEMPTSS-GDT
    TEMPCODE DESCRIPTOR <0ffffh,TEMPCODESEG,0,98H,>
    TEMPCODE_SEL = TEMPCODE-GDT
    SUBR     DESCRIPTOR <SUBRLEN-1,SUBRSEG,,4098H,>
    SUBR_SEL = SUBR-GDT+RPL3
    VIDEOBUFFER  DESCRIPTOR  <0FFFFH,0,0,0F00H+92H+DPL3,0>
    VIDEO_SEL = VIDEOBUFFER-GDT
    GDNUM = ($-EFFGDT)/(SIZE DESCRIPTOR)
    GDTLEN = $-GDT   
GDTSEG ENDS

DemoLDTSEG SEGMENT PARA USE16
    DEMOLDT     LABEL   BYTE
    DEMOSTACK0  DESCRIPTOR  <DEMOSTACK0LEN-1,DEMOSTACK0SEG,,92H+4000H,>
    DEMOSTACK0_SEL = (DEMOSTACK0-DEMOLDT)+TIL
    DEMOSTACK2  DESCRIPTOR  <DEMOSTACK2LEN-1,DEMOSTACK2SEG,,92H+4000H+40H,>
    DEMOSTACK2_SEL = (DEMOSTACK2-DEMOLDT)+TIL+RPL2
    DEMOCODE    DESCRIPTOR  <DEMOCODELEN-1,DEMOCODESEG,,4098H+40H,>
    DEMOCODE_SEL = DEMOCODE-DEMOLDT+TIL+RPL2
    DEMODATA    DESCRIPTOR  <DEMODATALEN-1,DEMODATASEG,,92H+4000H+60H,>
    DEMODATA_SEL = DEMODATA-DEMOLDT+TIL
    TODLDT      DESCRIPTOR  <DEMOLDTLEN-1,DemoLDTSEG,,92H+40H,>
    TODLDT_SEL = TODLDT-DEMOLDT+TIL
    TOTTSS      DESCRIPTOR  <TEMPTSSLEN-1,TEMPTSSSEG,,92H+40H,>
    TOTTSS_SEL = TOTTSS-DEMOLDT+TIL
   
    DEMOLDNUM = ($-DEMOLDT)/(SIZE DESCRIPTOR)
    TOSUBR   GATE  <SUBRB,SUBR_SEL,0,8CH+60H,0>
    TOSUBR_SEL = TOSUBR-DEMOLDT+TIL+RPL2
    TOTEMPT  GATE  <0,TEMPTSS_SEL,0,85H+60H,0>
    TOTEMPT_SEL = TOTEMPT-DEMOLDT+TIL
    DEMOLDTLEN = $-DEMOLDT
DemoLDTSEG ENDS

;----------------------------
DemoTSSSEG SEGMENT PARA USE16
      DD 0
      DD DemoStack0LEN
      DW DemoStack0_SEL,0
      DD 0
      DW ?,0
      DD DemoStack2LEN
      DW DemoStack2_SEL,0
      DD 0
      DW DEMOBEGIN,0
      DD 0
      DD 0
      DD 0
      DD 0
      DD 0
      DD DEMOSTACK2LEN
      DD 0
      DD 0
      DD 0B8000H
      DW VIDEO_SEL,0
      DW DEMOCODE_SEL,0
      DW DemoStack2_SEL,0
      DW DEMODATA_SEL,0
      DW TODLDT_SEL,0
      DW TOTTSS_SEL,0
      DW DEMOLDT_SEL,0
      DW 0
      DW $+2
      DB 0FFH
DemoTSSLEN = $
DemoTSSSEG ENDS     
     
;------------------------------
DemoStack0SEG SEGMENT PARA USE32
DemoStack0LEN = 1024
      DB DemoStack0LEN DUP(0)
DemoStack0SEG ENDS  

DemoStack2SEG SEGMENT PARA USE32
DemoStack2LEN = 512
      DB DemoStack2LEN DUP(0)
DemoStack2SEG ENDS

DEMODATASEG SEGMENT PARA USE32
MESSAGE DB 'VALUE = ',0
DEMODATALEN = $
DEMODATASEG ENDS

;-----------------------------
SUBRSEG SEGMENT PARA USE32
      ASSUME CS:SUBRSEG
SUBRB PROC FAR
      PUSH EBP
      MOV EBP,ESP
      PUSHAD
      MOV EAX,[EBP+12]
      MOV ESI,EAX
      MOV AH,7
      JMP SHORT SUBR2
SUBR1:STOSW
SUBR2:LODSB
      OR AL,AL
      JNZ SUBR1
      MOV EDX,[EBP+16]
      MOV ECX,8     
SUBR3:ROL EDX,4
      MOV AL,DL
      CALL HTOASC
      STOSW
      LOOP SUBR3     
      POPAD
      POP EBP
      RET 8
SUBRB ENDP

HTOASC PROC
      AND AL,0FH
      ADD AL,90H
      DAA
      ADC AL,40H
      DAA
      RET
HTOASC ENDP                      
SUBRLEN = $
SUBRSEG ENDS


;-----------------------------
DemoCodeSEG SEGMENT PARA USE32
      ASSUME CS:DemoCodeSEG
DemoBegin:
      MOV FS:TOSUBR.DCOUNT,2
      PUSH DWORD PTR GS:TEMPTASK.TREIP
      PUSH OFFSET MESSAGE
      CALL32 TOSUBR_SEL,0
      ASSUME DS:TEMPTSSSEG
      PUSH GS
      POP DS
      MOV AX,NORMAL_SEL
      MOV TEMPTASK.TRDS,AX
      MOV TEMPTASK.TRES,AX
      MOV TEMPTASK.TRFS,AX
      MOV TEMPTASK.TRGS,AX
      MOV TEMPTASK.TRSS,AX
      JUMP32 TOTEMPT_SEL,0
DemoCodeLEN = $
DemoCodeSEG ENDS           

TEMPTSSSEG SEGMENT PARA USE16
TEMPTASK TASKSS <>
         DB 0FFH
TEMPTSSLEN = $
TEMPTSSSEG ENDS        

;-----------------------------
TempCodeSEG SEGMENT PARA USE16
      ASSUME CS:TempCodeSEG
VIRTUAL:
      MOV BX,TEMPTSS_SEL
      LTR BX
      JUMP16 DEMOTSS_SEL,0
TOREAL:
      CLTS
      MOV EAX,CR0
      AND AX,0FFFEH
      MOV CR0,EAX
      JUMP16 <SEG REAL>,<OFFSET REAL>
TempCodeLEN = $
TempCodeSEG ENDS                

;---------------------------
RDataSeg SEGMENT PARA USE16
    VGDTR  PDESC  <GDTLEN-1,>
    SPVAR  DW     ?
    SSVAR  DW     ?
RDataSeg ENDS

;---------------------------
RCodeSEG SEGMENT PARA USE16
      ASSUME CS:RCodeSEG,DS:RDataSeg
START:
      MOV AX,RDataSeg
      MOV DS,AX
      CLD
      CALL INIT_GDT
     
      MOV AX,DemoLDTSEG
      MOV FS,AX
      MOV SI,OFFSET DemoLDT
      MOV CX,DemoLDNUM
      CALL INIT_LDT
     
      MOV SSVAR,SS
      MOV SPVAR,SP
      LGDT QWORD PTR VGDTR
      CLI
      MOV EAX,CR0
      OR EAX,1
      MOV CR0,EAX
      JUMP16 TempCode_SEL,<OFFSET Virtual>
REAL:
      MOV AX,RDataSeg
      MOV DS,AX
      LSS SP,DWORD PTR SPVAR
      STI
      MOV AH,4CH
      INT 21H

INIT_GDT PROC NEAR
      PUSH DS
      MOV AX,GDTSEG
      MOV DS,AX
      MOV CX,GDNUM
      MOV SI,OFFSET EFFGDT
INITG:MOV AX,[SI].BASEL
      MOVZX EAX,AX
      SHL EAX,4
      SHLD EDX,EAX,16
      MOV [SI].BASEL,AX
      MOV [SI].BASEM,DL
      MOV [SI].BASEH,DH
      ADD SI,SIZE DESCRIPTOR
      LOOP INITG
      POP DS
     
      MOV BX,16
      MOV AX,GDTSEG
      MUL BX
      MOV WORD PTR VGDTR.BASE,AX
      MOV WORD PTR VGDTR.BASE+2,DX
      RET
INIT_GDT ENDP

INIT_LDT PROC
ILDT: MOV AX,FS:[SI].BASEL
      MOVZX EAX,AX
      SHL EAX,4
      SHLD EDX,EAX,16
      MOV FS:[SI].BASEL,AX
      MOV FS:[SI].BASEM,DL
      MOV FS:[SI].BASEH,DH
      ADD SI,SIZE DESCRIPTOR
      LOOP ILDT
      RET
      INIT_LDT ENDP
RCodeSEG ENDS
      END START