v86.asm

来自「windows下汇编语言 学习汇编语言好助手」· 汇编 代码 · 共 253 行

ASM
253
字号
;***********************************
;文件:V86.asm                     *
;功能:用任务转移的方法进入V86方式 *
;***********************************
.386p
JUMP16 MACRO selector,offsetv
        DB 0EAH
        DW offsetv
        DW selector
       ENDM
;----------------------       
Descriptor STRUC
	limitl     dw 0
	basel	   dw 0
	basem 	   db 0
	attrib	   dw 0
	baseh      db 0
Descriptor ENDS       
;----------------------       
Gate STRUC
	offsetl  dw 0
	selector dw 0
	dcount   db 0
	gtype    db 0
	offseth  dw 0
Gate ENDS
;===============================
Data Segment use16
	gdt0 Descriptor <>

	DataSel = $-gdt0
	DataDes Descriptor <0ffffh,,,92H,>
	
	AllSel = $-gdt0
	AllDes Descriptor  <0ffffH,,,0F92H,>
	
	CodeSel = $-gdt0
	CodeDes Descriptor <0ffffh,,,98H,>
		
	TssV86Sel = $-gdt0                       ;TssV86 Descriptor
	TssV86Des Descriptor <TssV86Len-1,,,89H,>

    TssTSel = $-gdt0                       ;TSS Descriptor
    TssTDes Descriptor <TssTLen-1,,,89H,>
	
	GdtLen  = $-gdt0
	
	GdtPtr  dw GdtLen-1 
			dd 0
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++			
        StackBuff db 1024 dup (0)
        StackTop label byte

        OldSPSS dw 0,0
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        TssTemp dd 0
                dd 0       ;Stack Pointer for Ring 0
                dw 0,0
                dd 0       ;Stack Pointer for Ring 1
                dw 0,0
                dd 0       ;Stack Pointer for Ring 2
                dw 0,0
                dd 0       ;cr3
                dd 0       ;eip  
                dd 0       ;eflags
                dd ?       ;eax
                dd ?       ;ecx
                dd ?       ;edx
                dd ?       ;ebx
                dd ?       ;esp
                dd ?       ;ebp
                dd ?       ;esi
                dd ?       ;edi
                dw 0,0     ;es
                dw 0,0     ;cs
                dw 0,0     ;ss
                dw 0,0     ;ds
                dw 0,0     ;fs
                dw 0,0     ;gs
                dw 0,0     ;ldt       
                dw 0         
                dw 68H
                db 0ffh
        TssTLen = $-TssTemp

        TssV86     dd 0
                dd StackTop  ;Stack Pointer for Ring 0
                dw DataSel,0
                dd 0         ;Stack Pointer for Ring 1
                dw 0,0
                dd 0         ;Stack Pointer for Ring 2
                dw 0,0
                dd 0         ;cr3
                dw offset V86,0       ;eip  
                dd 00023000H          ;eflags
                dd ?            ;eax
                dd ?            ;ecx
                dd ?            ;edx
                dd ?            ;ebx
                dd 0            ;esp
                dd ?            ;ebp
                dd ?            ;esi
                dd ?            ;edi
                dw Data,0       ;es
                dw Code,0       ;cs
                dw Data,0       ;ss
                dw Data,0       ;ds
                dw Data,0       ;fs
                dw Data,0       ;gs
                dw 0,0          ;ldt       
                dw 0         
                dw 68H
                db 65536/8 dup (0)
                db 0ffh
        TssV86Len = $-TssV86
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	IdtPtr	dw IdtLen-1
			dd 0
	IdtTable label byte
		Off = offset IntProc
	REPT 256
		Gate<Off,CodeSel,0,0EEH,0>
                Off=Off+(All-IntProc)/256
	ENDM
	
	IdtLen = $-IdtTable
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	DataLen = $-gdt0									
Data ends
;================================
Code Segment use16
	assume cs:Code,ds:Data
IntProc:
	COUNT = 0
	REPT 256
        push word ptr COUNT
        push ax
        mov ax,offset All
        jmp ax
		COUNT = COUNT+1
	ENDM
All:
	pop ax
	push bp
	mov bp,sp
	add bp,4
	push eax
	push esi
	mov ax,AllSel
	mov ds,ax
	
	xor  eax,eax
	mov  esi,[bp+10h]
	mov  ax,[bp+0ch]
	shl  esi,4
	add  eax,esi
	mov  esi,[bp+8]   ;flag
	mov  [eax-2],si
	mov  esi,[bp+4]   ;cs
	mov  [eax-4],si
	mov  esi,[bp+0]   ;ip
	mov  [eax-6],si

	xor  esi,esi
	mov  si,[bp-2]
	shl  esi,2
	lodsd
	mov  [bp+0],ax    ;ip
	shr  eax,10h
	mov  [bp+4],ax    ;cs
	mov  eax,[bp+0ch]
	sub  eax,6
	mov  [bp+0ch],eax ;sp

	mov eax,[bp+8]
	or eax,23000H
;    and eax,0fffffeffH
	and eax,0fffffCffH
	mov [bp+8],eax
	pop     esi
	pop     eax
	pop     bp
	add     sp,02h
	iretd

Start:
	mov ax,Data
	mov ds,ax
		
	xor eax,eax
	mov ax,Data
	shl eax,4
	mov dword ptr [GdtPtr+2],eax	;GDT地址
	mov ax,Data
	movzx eax,ax
	shl eax,4
	add eax,offset IdtTable
	mov dword ptr [IdtPtr+2],eax	;IDT地址
	mov DataDes.basel,ax	;初始化数据段描述符
	shr eax,16
	mov DataDes.basem,al
	mov DataDes.baseh,ah
	xor eax,eax				;初始化代码段描述符
	mov ax,Code
	shl eax,4
	mov CodeDes.basel,ax
	shr eax,16
	mov CodeDes.basem,al
	mov CodeDes.baseh,ah
	mov ax,Data		         ;TssV86
	movzx eax,ax
	shl eax,4
	add eax,offset TssV86
	mov TssV86Des.basel,ax
	shr eax,16
	mov TssV86Des.basem,al
	mov TssV86Des.baseh,ah
	mov ax,Data               ;tssTemp
	movzx eax,ax
	shl eax,4
	add eax,offset TssTemp
	mov TssTDes.basel,ax
	shr eax,16
	mov TssTDes.basem,al
	mov TssTDes.baseh,ah
	
	lgdt qword ptr GdtPtr	   ;Load GDT
	cli
	lidt qword ptr IdtPtr      ;Load IDT
	mov OldSPSS,sp
	mov [OldSPSS+2],ss
	mov eax,cr0				   ;转到保护模式模式
	or eax,1
	mov cr0,eax
	JUMP16 CodeSEL,<offset Protect>
Protect:
	mov ax,TssTSel
	ltr ax
	clts
	JUMP16 TssV86Sel,0        
V86:
	mov ax,data
	mov ds,ax
	lss sp,dword ptr OldSPSS
	sti
	MOV AX,3100H
	mov dx,offset start + DataLen
	shr dx,4
	add dx,12h
	INT 21H        
Code ends
	end Start

⌨️ 快捷键说明

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