interrup.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 1,848 行 · 第 1/4 页
ASM
1,848 行
mov ds,ax
assume ds:_cwDPMIEMU
movzx eax,bl
mov ebx,eax
shl ebx,1 ;*2
mov eax,ebx
shl ebx,1 ;*4
add ebx,eax ;*6
add ebx,offset InterruptTable
pushf
cli
mov [ebx],edx ;set offset.
mov [ebx+4],cx ;set segment selector.
popf
pop gs
pop fs
pop es
pop ds
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop eax
ret
RawSetVector endp
;-------------------------------------------------------------------------------
;
;Set real mode interupt handler address.
;
;On Entry:-
;
;BL - Interupt vector number.
;CX:DX - selector:offset of new handler.
;
;On Exit:-
;
;CF set on error.
;
RawSetRVector proc near
;
push eax
push ebx
push ecx
push edx
push esi
push edi
push ebp
push ds
push es
push fs
push gs
mov ax,KernalZero
mov es,ax
movzx ebx,bl
shl ebx,2
pushf
cli
mov es:[ebx],dx
mov es:[ebx+2],cx
popf
pop gs
pop fs
pop es
pop ds
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop eax
ret
RawSetRVector endp
;-------------------------------------------------------------------------------
;
;Set protected mode exception handler address.
;
;On Entry:-
;
;BL - Exception vector number.
;CX:EDX - selector:offset of new handler.
;
;On Exit:-
;
;CF set on error.
;
RawSetEVector proc near
;
; pushm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
push ds
push es
push fs
push gs
push ebx
push ecx
push edx
push esi
push edi
push ebp
push eax ; push last so is easily accessible for changing
mov ax,DpmiEmuDS
mov ds,ax
movzx eax,bl
push eax
mov ebx,eax
shl ebx,1 ;*2
mov eax,ebx
shl ebx,1 ;*4
add ebx,eax ;*6
pop eax
add ebx,offset ExceptionTable
;
cmp al,14 ;Special case for 14
; jnz @@Normal
je Special14x ; MED 01/17/96
cmp al,20h
jc inter11_Normal
stc ; flag error
pop eax
mov ax,8021h ; flag invalid value
push eax
jmp inter11_GotVect ; don't set vector
Special14x:
cmp w[OldExcep14+4],0 ;Virtual memory active?
jz inter11_Normal
;
;Vector 14 and VMM is still installed.
;
mov d[OldExcep14],edx
mov w[OldExcep14+4],cx
jmp inter11_GotVect
inter11_Normal: ;
clc ; MED 01/17/96, flag no error
mov [ebx],edx ;set offset.
mov [ebx+4],cx ;set segment selector.
inter11_GotVect: ;
; popm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
pop eax
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop gs
pop fs
pop es
pop ds
ret
RawSetEVector endp
;-------------------------------------------------------------------------------
;
;Allocate a real mode call back address.
;
;On Entry:-
;
;DS:ESI - Protected mode code.
;ES:EDI - Real mode register structure.
;
;On Exit:-
;
;Carry set on error, else,
;
;CX:DX - Real mode address allocated.
;
RAWGetCallBack proc near
;
push eax
push ebx
push esi
push edi
push ebp
push ds
push es
mov ax,ds
push ax
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
pop ax
;
;;MED 02/16/96
mov ebx,offset CallBackTable+((size CallBackStruc)*(16+3))
mov ecx,MaxCallBacks-(16+3)
mov edx,16+3
; mov ebx,offset CallBackTable+((size CallBackStruc)*(16+4))
; mov ecx,MaxCallBacks-(16+4)
; mov edx,16+4
inter12_0: test CallBackStruc.CallBackFlags[ebx],1 ;this one in use?
jz inter12_1
add ebx,size CallBackStruc
inc edx
dec ecx
jnz inter12_0
jmp inter12_9
;
inter12_1: pushad
xor eax,eax
mov cx,1
int 31h
mov w[CallBackStruc.CallBackStackSel+ebx],ax
popad
jc inter12_9
pushad
mov bx,w[CallBackStruc.CallBackStackSel+ebx]
mov eax,8
xor ecx,ecx
or edx,-1
int 31h
popad
;
mov w[CallBackStruc.CallBackProt+4+ebx],ax ;store protected mode code address.
mov d[CallBackStruc.CallBackProt+0+ebx],esi ;/
mov w[CallBackStruc.CallBackRegs+4+ebx],es ;store register table address.
mov d[CallBackStruc.CallBackRegs+0+ebx],edi ;/
mov ax,CallBackSize
mul dx
mov esi,offset CallBackList
movzx eax,ax
add esi,eax ;index list of calls.
mov CallBackStruc.CallBackOff[ebx],si ;store call back address.
mov CallBackStruc.CallBackFlags[ebx],1 ;flag this entry in use.
mov ax,_cwRaw
mov cx,ax ;get real mode code seg.
mov dx,si ;get real mode offset.
clc
jmp inter12_10
;
inter12_9: stc
inter12_10:
pop es
pop ds
pop ebp
pop edi
pop esi
pop ebx
pop eax
ret
assume ds:_cwDPMIEMU
RAWGetCallBack endp
;-------------------------------------------------------------------------------
;
;Release a previously allocated real mode call back address.
;
;On Entry:-
;
;CX:DX - Real mode call back address.
;
RAWRelCallBack proc near
;
pushad
push ds
push es
push fs
push gs
push ax
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
pop ax
;
mov esi,offset CallBackTable
mov ebx,MaxCallBacks
inter13_0: test CallBackStruc.CallBackFlags[esi],1
jz inter13_1
cmp dx,CallBackStruc.CallBackOff[esi]
jnz inter13_1
mov CallBackStruc.CallBackFlags[esi],0
mov bx,CallBackStruc.CallBackStackSel[esi]
mov ax,1
int 31h
clc
jmp inter13_2
;
inter13_1: add esi,size CallBackStruc
dec ebx
jnz inter13_0
stc
;
inter13_2:
pop gs
pop fs
pop es
pop ds
popad
ret
assume ds:_cwDPMIEMU
RAWRelCallBack endp
;-------------------------------------------------------------------------------
;
;Need to retrieve the interupt number.
;
IntHandler proc near
push ds
push eax
mov ax,DpmiEmuDS ;make our data addresable.
mov ds,ax ;/
movzx esp,sp ;our stack never >64k.
mov eax,[esp+(4+4)] ;get return address.
sub eax,offset InterruptHandler
shr eax,3 ;convert it to an interrupt number.
mov ExceptionIndex,eax ;/
;
;Check if this is an exception or interrupt (any error code)
;
cmp esp,tPL0StackSize-4-((4+4)+(4)+(4)+(4+4+4)+(4+4))
; | | | | |
; EAX:DS --------------------/ | | | |
; | | | |
; Return address -----------------/ | | |
; | | |
; Error code -------------------------/ | |
; | |
; EIP:CS:Eflags ----------------------------/ |
; |
; ESP:SS ------------------------------------------/
;
jnz inter14_NoCode
and w[esp+(4+4)+(4)+(4)+(4+4)],0011111111010101b
; MED 12/02/95
; check if Exception Index is 0dh
; if so and instruction at CS:EIP is:
; mov eax,cr0 [0f 20 c0] or
; mov cr0,eax [0f 22 c0] or
; mov eax,cr3 [0f 20 d8] or
; mov cr3,eax [0f 22 d8]
; then emulate it here and return
; MED 11/12/98, emulate RDMSR [0f 32]
; MED 04/05/99, emulate WBINVD [0f 09]
; WRMSR [0f 30]
; mov eax,cr4 [0f 20 e0]
; mov cr4,eax [0f 22 e0]
; MED 05/02/2000, mov ebx,cr4 [0f 20 e3]
; mov eax,cr2 [0f 20 d0]
push ds
cmp eax,0dh
jne mednoem ; not a GPF
mov ax,ss:[esp+(4+4)+(4)+(4+4)+4] ; ax==original CS
; verr ax ; check for looping lockup invalid value
; jnz mednoem
mov ds,ax
mov eax,ss:[esp+(4+4)+(4)+(4)+4] ; eax==original EIP
cmp BYTE PTR ds:[eax],0fh ; first opcode byte
jne mednoem ; no match
cmp WORD PTR ds:[eax+1],0c020h ; mov eax,cr0
jne med2b
mov eax,cr0
mov ss:[esp+4],eax ; update original eax with cr0 value
jmp medemu
med2b:
cmp WORD PTR ds:[eax+1],0c022h ; move cr0,eax
jne med3b ; no match
mov eax,ss:[esp+4] ; get original eax value
mov cr0,eax ; update cr0 value with original eax
jmp medemu
med3b:
cmp WORD PTR ds:[eax+1],0d820h ; mov eax,cr3
jne med4b
mov eax,cr3
mov ss:[esp+4],eax ; update original eax with cr3 value
jmp medemu
med4b:
cmp WORD PTR ds:[eax+1],0d822h ; move cr3,eax
jne med5b ; no match
mov eax,ss:[esp+4] ; get original eax value
mov cr3,eax ; update cr3 value with original eax
jmp medemu
med5b:
cmp WORD PTR ds:[eax+1],0e022h ; move cr4,eax
jne med6b ; no match
mov eax,ss:[esp+4] ; get original eax value
.586
mov cr4,eax ; update cr4 value with original eax
jmp medemu
med6b:
cmp WORD PTR ds:[eax+1],0e020h ; mov eax,cr4
jne med7b
.586
mov eax,cr4
mov ss:[esp+4],eax ; update original eax with cr4 value
jmp medemu
med7b:
cmp BYTE PTR ds:[eax+1],9 ; WBINVD
jne med8b
.586
wbinvd
mov eax,2
jmp medemu2
med8b:
cmp BYTE PTR ds:[eax+1],30h ; WRMSR
jne med9b
.586
mov eax,ss:[esp+4] ; get original eax value
wrmsr
mov eax,2
jmp medemu2
med9b:
cmp BYTE PTR ds:[eax+1],32h ; RDMSR
jne med10b
; push eax
.586
rdmsr
; DB 0fh ; RDMSR instruction
; DB 32h
; mov ss:[esp+8],eax ; update original eax value
; pop eax
mov ss:[esp+4],eax ; update original eax value
mov eax,2
jmp medemu2
med10b:
cmp WORD PTR ds:[eax+1],0e320h ; mov ebx,cr4
jne med11b ; no match
.586
mov ebx,cr4
jmp medemu
med11b:
cmp WORD PTR ds:[eax+1],0d020h ; mov eax,cr2
jne mednoem
mov eax,cr2
mov ss:[esp+4],eax ; update original eax with cr2 value
; jmp medemu
medemu:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?