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

📄 vbare.asm

📁 windows汇编语言程序设计 吴中平著 一书所附所有源代码。 该书重点讲解了Windows环境下汇编语言程序设计的基本原理及其实现过程
💻 ASM
📖 第 1 页 / 共 2 页
字号:
                    TITLE      program under protection
;pure english in this text,chinese in virtual.asm.
PDT_ADDR     equ 00300000H
PT_0_ADDR    equ 00301000H
PTC_CODE     equ 003FF000H
PTC_TEST     equ 003FE000H
PTC_VIDEO    equ 003FA000H
PhTestMem    equ 08FFF000H
PhExeMem     equ 00FFF000H


include dos.inc
.386p
GDTSEG Segment PARA USE16
gdt LABEL BYTE
     Dummy DESCRIPTOR <>;selector=0
     Normal DESCRIPTOR <0ffffH,0,0,ATTDW,0>
         NORMAL_SEL=Normal-gdt;selector=8
     ExtMem DESCRIPTOR <0FFFFh,0eaa0h,010h,ATTDR,0>
         EXTMEM_SEL=ExtMem-gdt
     EchoBuffer DESCRIPTOR <0ffffH,8000H,0BH,ATTDW,0>
         ECHO_BUFFER_SEL=EchoBuffer-gdt
;=============================================================================
     CopyCodeBuffer  DESCRIPTOR <0FFFFH,PhExeMem and 0FFFFH,PhExeMem shr 16,ATTDW,0>
         COPY_SEL=CopyCodeBuffer-gdt
     V_P_Code DESCRIPTOR <0FFFFH,PTC_CODE AND 0FFFFH,PTC_CODE shr 16,ATTCER,0>
         V_P_CODE_SEL=V_P_Code-gdt
     V_P_Video DESCRIPTOR <0FFFFH,PTC_VIDEO AND 0FFFFH,PTC_VIDEO shr 16,ATTDW,0>
         V_P_VIDEO_SEL=V_P_Video-gdt
     V_P_PDTable DESCRIPTOR <0FFFH,PDT_ADDR AND 0FFFFH,PDT_ADDR shr 16,ATTDW,0>
         V_P_PDT_SEL=V_P_PDTable-gdt
     V_P_PT_0 DESCRIPTOR <0FFFH,PT_0_ADDR AND 0FFFFH,PT_0_ADDR shr 16,ATTDW,0>
         V_P_PT_0_SEL=V_P_PT_0-gdt
         
;-----------------------------------------------------------------------------
Gdt_Init_Start LABEL BYTE
     SwitchCon DESCRIPTOR<0FFFFH,ControlSeg,?,ATTCER,?>
         SWITCH_SEL=SwitchCon-gdt
     MainCode DESCRIPTOR <MAINCODELENGTH-1,MainCodeSeg,?,ATTCER,?>
         MAINCODE_SEL=MainCode-gdt
     MainData DESCRIPTOR <0FFFFH,MainDataSeg,?,ATTDW,?>
         MAINDATA_SEL=MainData-gdt
     MainLdt DESCRIPTOR <MAINLDTLENGTH-1,MainLDTSeg,0,ATTLDT,?>
         MAINLDT_SEL=MainLdt-gdt
     MainTss DESCRIPTOR <MAINTSSLENGTH-1,MainTSSSeg,?,ATTTSS,?>
         MAINTSS_SEL=MainTss-gdt
     MainTSS_Alias DESCRIPTOR <MAINTSSLENGTH-1,MainTSSSeg,?,ATTDW,?>
         MAINTSS_ALIAS_SEL=MainTss_Alias-gdt
         
     MainStack_0    DESCRIPTOR <MAINSTACK_POINTER_0-1,MainStackSeg_0,?,ATTDW,?>
         MAINSTACK_0_SEL=MainStack_0-gdt
     MainStack_2    DESCRIPTOR <MAINSTACK_POINTER_2-1,MainStackSeg_2,?,ATTDW+DPL2,?>
         MAINSTACK_2_SEL=MainStack_2-gdt+RPL2              
     DosTss DESCRIPTOR <DOSTSSLENGTH-1,DosTSSSeg,?,ATTTSS,?>
         DOSTSS_SEL=DosTss-gdt
     DosLdt DESCRIPTOR <DOSLDTLENGTH-1,DosLDTSeg,?,ATTLDT,?>
         DOSLDT_SEL=DosLdt-gdt
     GDT_INIT_NUM=($-Gdt_Init_Start)/(SIZE DESCRIPTOR)
     GDTLENGTH=$-gdt
GDTSEG EndS

IDTSEG Segment para use16
     idt LABEL BYTE
     rept 13
     GATE <Int_Pro,MAINCODE_SEL,0,ATTTGAT,0>
     EndM
     GATE <Int_D,MAINCODE_SEL,0,ATTTGAT,0>
     rept 19
     GATE <Int_Pro,MAINCODE_SEL,0,ATTTGAT,0>
     EndM
INT_DOS21 GATE <?,DOSTSS_SEL,0,ATTTASKGAT,0>
     rept 220
     GATE <Int_Pro,MAINCODE_SEL,0,ATTTGAT,0>
     EndM
INT_PAGE  GATE <IntPage,MAINCODE_SEL,0,ATTIGAT,0>
     GATE <Int_Pro,MAINCODE_SEL,0,ATTTGAT,0>
     IDTLENGTH=$-idt
IDTSEG Ends

MainTSSSeg Segment para use16
     Main_TSS  taskss   <>
              DB 0ffh
     MAINTSSLENGTH=$
MainTSSSeg Ends

MainStackSeg_0 Segment para use16
     MAINSTACK_POINTER_0 =1024
     db  MAINSTACK_POINTER_0   dup(0)
MainStackSeg_0 Ends

MainStackSeg_2 Segment para use16
     MAINSTACK_POINTER_2 =1024
     db  MAINSTACK_POINTER_2   dup(0)
MainStackSeg_2 Ends

MainLDTSeg Segment para use16
No_Init LABEL BYTE
     CallGate Gate <ReturnLevel_0_Entry,SWITCH_SEL,1,ATTCGAT+DPL2,0>
         LEVEL2GATE_SEL=CallGate-No_Init+TIL+RPL2
MainLdt_Init_Start LABEL BYTE
     GetExMemDe DESCRIPTOR <MAINCODELENGTH-1,MainCodeSeg,0,ATTCER,0>
         VISITEXMEM_SEL=GetExMemDe-No_Init+TIL
     Level2De DESCRIPTOR <LEVEL2LENGTH-1,CodeSeg_2,0,ATTCER+DPL2,0>
         LEVEL2_SEL=Level2De-No_Init+TIL+RPL2
     MAINLDT_INIT_NUM=($-MainLdt_Init_Start)/(SIZE DESCRIPTOR)
     MAINLDTLENGTH=$
MainLDTSeg Ends

MainDataSeg  Segment PARA use16
     ExtMemMess db "1----The Content of Memory at FFFF:EAB0(since 10EAA0 for 16 bytes)is :",0dh,0ah
     EMM_LEN=$-ExtMemMess
     Buffer_ExtMem db 50 dup(0)
     DPLConvert db "2----DPL is Changed(LEVEL0-->LEVEL2-->LEVEL0),Copy 12345678H from LEVEL2 stack!"
     DPL_LEN=$-DPLConvert
     Buffer_DPL db 16 dup(0)
     Int_D_Mess db "3----General Protect happend!"
     D_LEN =$-Int_D_Mess
     Int_Pro_Mess db "4----Other Interrupt happened!"
     P_LEN=$-Int_Pro_Mess
     PageManage db "5----The Content of Page_0 Item:"
     PAGE_LEN=$-PageManage
     Buffer_Page db 8 dup(?)
MainDataSeg Ends

MainCodeSeg Segment PARA use16
assume cs:MainCodeSeg
Dis_play proc
     push di
     cld
again:
     lodsb
     mov ah,34h
     stosw
     loop again
     pop di
     retf
     COPYLEN=$-Dis_Play
Dis_play endp


GetExMem proc
      mov ax,EXTMEM_SEL
      mov ds,ax
      mov si,0
      mov ax,MAINDATA_SEL
      mov es,ax      
      lea di,Buffer_ExtMem
      mov cx,16
      cld
changeasc:
      lodsb
      call  far ptr  ToAscii
      stosw
      mov al,' '
      stosb
      loop changeAsc
      mov al,'$'
      stosb
      retf
GetExMem endp


ToAscii proc
     push ax
     shr al,4
     and al,0fh
     add al,90h
     daa
     adc al,40h
     daa
     mov bl,al
     pop  ax
     and al,0fh
     add al,90h
     daa
     adc al,40h
     daa
     mov bh,al
     mov ax,bx
     retf
ToAscii endp

Int_Pro proc

     mov ax,MAINDATA_SEL
     mov ds,ax
     lea si,Int_Pro_Mess
     mov ax,ECHO_BUFFER_SEL
     mov es,ax
     mov di,160*8
     mov cx,P_LEN
     call  FAR ptr dis_play
     iretd
Int_Pro Endp

Int_D proc

     mov ax,MAINDATA_SEL
     mov ds,ax
     Lea si,Int_D_Mess
     mov ax,ECHO_BUFFER_SEL
     mov es,ax
     mov di,160*6
     mov cx,D_LEN
     call  Far ptr dis_play
     pop eax
     pop eax
     add eax,7
     push eax
     iretd
Int_D Endp



IntPage Proc

     mov ax,MAINCODE_SEL
     mov ds,ax
     lea si,Dis_play
     mov ax,COPY_SEL
     mov es,ax
     xor di,di
     mov ecx,COPYLEN
     rep movsb

     mov ax,V_P_PDT_SEL
     mov es,ax
     xor di,di
     mov cx,1024
     xor eax,eax
     REP STOSD
     mov dword ptr es:[0],PT_0_ADDR+USU+RWW+PL

     mov ax,V_P_PT_0_SEL
     mov es,ax
     xor di,di
     mov cx,1024
     xor eax,eax
     mov  eax,3
init_item:
     stosd
     add eax,1000H
     loop init_item
     mov di,(PT_0_ADDR shr 12)*4
     mov dword ptr es:[di],PT_0_ADDR +USU+RWR+PL
     mov di,(PTC_VIDEO shr 12)*4;3faH
     mov dword ptr es:[di],0B8000H+USu+RWW+PL
     mov di,(PTC_TEST shr 12)*4;3feH
     mov dword ptr es:[di],PhTestMem+USU+RWW+PL
     mov di,(PTC_CODE shr 12)*4;3ffH
     mov dword ptr es:[di],PhExeMem+USU+RWR+PL

     mov eax,PDT_ADDR
     mov cr3,eax
     mov eax,cr0
     or eax,80000000H
     mov cr0,eax

     mov di,160*10
     mov cx,6
     mov ax,V_P_PT_0_SEL
     mov ds,ax
     mov bx,(PTC_VIDEO shr 12)*4
nextitem:
     push ds
     push bx
     push cx
     push di
     mov edx,dword ptr ds:[bx]
     mov ax,MAINDATA_SEL
     mov es,ax
     lea di,Buffer_Page
     mov cx,4
page_toa_c:
     rol edx,8
     mov al,dl
     Call_16 MAINCODE_SEL,ToAscii;
     stosw
     loop page_toa_c
     mov ax,MAINDATA_SEL
     mov ds,ax
     lea si,Buffer_Page
     mov ax,V_P_VIDEO_SEL;
     mov es,ax
     pop di
     add di,160
     mov cx,8
     call_16 < V_P_CODE_SEL>,<offset Dis_Play>
     pop cx
     pop bx
     add bx,4
     pop ds
     loop nextitem

     mov eax,cr0
     and eax,7fffffffh
     mov cr0,eax
     iretd
IntPage Endp
     MAINCODELENGTH=$
MainCodeSeg Ends



CodeSeg_2 Segment para use16;DPL2
assume cs:CodeSeg_2
Level2:
    push 12345678H
    call_16   LEVEL2GATE_SEL,<offset ReturnLevel_0_Entry>
LEVEL2LENGTH=$
CodeSeg_2 Ends


DosLDTSeg Segment para use16
DosLdt_Init_Start label byte
     DosData  DESCRIPTOR<DOSDATALENGTH-1,DosDataSeg,0,ATTDW,0>
         DOSDATA_SEL=DosData-DosLDT_Init_Start+TIL
     DosStack DESCRIPTOR<DOSSTACKLENGTH-1,DosStackSeg,0,ATTDW,0>
         DOSSTACK_SEL=DosStack-DosLDT_Init_Start+TIL
     DosCode DESCRIPTOR<0ffffh,DosCodeSeg,0,ATTCER,0>
         DOSCODE_SEL=DosCode-DosLDT_Init_Start+TIL
     DOSLDT_INIT_NUM=($-DosLdt_Init_Start)/(SIZE DESCRIPTOR)
     DOSLDTLENGTH=$-DosLdt_Init_Start
DosLDTSeg Ends


DosDataSeg Segment para use16
     DosMess db  0dh,0ah, "Press any key to Exit!"
     DOSMESSLEN=$-DosMess
     DOSDATALENGTH=$
DosDataSeg Ends

DosStackSeg Segment para use16
     DOSSTACK_POINTER =1024             
     db DOSSTACK_POINTER dup(0)
     DOSSTACKLENGTH=$
DosStackSeg Ends

DosCodeSeg Segment para use16

⌨️ 快捷键说明

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