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

📄 intr.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	jc exc_user			; if yes, branch
	mov ah,cs:last_int		; put last int number in AH
	jmp dword ptr cs:client_call	; use default exception handler


;=============================================================================
exc_handler:
	pop ax
	sub ax,offs exc_matrix+1
	shr ax,2
	mov ah,cs:last_int
	jmp dword ptr cs:client_call	; use default exception handler



;-----------------------------------------------------------------------------
; User Exception Handler
;
exc_user:
	push bx
	mov bx,ax
	shl bx,3
	sub esp,4				; 4 bytes on stack for 00:CS
	mov ax,word ptr cs:exctab_pm[bx+0]	; get offset low (EIP)
	mov [esp+0],ax
	mov ax,word ptr cs:exctab_pm[bx+2]	; get offset high (EIP)
	mov [esp+2],ax
	mov bx,word ptr cs:exctab_pm[bx+4]	; get selector (CS:)
	xchg bx,[esp+4]			; put CS and restore BX
	mov ax,[esp+6]			; restore AX
	db 66h				; do 32bit far ret to the
	retf				;  appropriate exception handler







; Standard IRQ Handler
;
; This handler will always, when called, send IRQs from protected mode to
; real mode
;
;=============================================================================
irq_standard:				; Standard IRQ handler that will send
	cli
	pop ax				; by default all the IRQs from
	sub ax,offs std_matrix+1	; protected mode to real mode
	shr ax,2
	pushad
	push ds es fs gs
	mov ds,cs:seldata
	inc _pc_irqpmtorm		; increment IRQ PM->RM counter
	xor esi,esi
	mov dx,rmstacktop		; DX = SS for real mode redirection
	xor ecx,ecx
	mov bx,rmstacklen		; get size of real mode stack
	mov si,dx			; ESI -> top of real mode stack
	sub dx,bx			; adjust DX to next stack location
	mov cl,al
	shl esi,4
	cmp dx,rmstackbase		; exceeded real mode stack space?
	jb critical_error_rm		; if yes, critical error
	mov rmstacktop,dx		; update ptr for possible reenterancy
	shl bx,4			; set real mode SP to top of stack
	mov edi,irqtab_rm[ecx*4]	; get real mode interrupt CS:IP
	mov ds,selzero			; DS -> 0 (beginning of memory)
	mov [esi-2],ss			; store SS: on real mode stack
	mov [esi-6],esp			; store ESP on real mode stack
	mov dword ptr [esi-10],_KERNEL	; set target FLAGS and CS: on RM stack
	mov word ptr [esi-12],offs @irq	; set target IP on RM stack
	shld esi,edi,16
	sub bx,12			; adjust real mode SP for stored vars
	db 66h				; JMP DWORD PTR, as in 32bit offset,
	jmp word ptr cs:pmtormswrout	;  not seg:16bit offset

@irq:	cli
	mov ax,SELDATA			; DS selector value for protected mode
	mov cx,ax			; ES selector value for protected mode
	pop ebx				; get protected mode SS:ESP from stack
	pop dx
	mov si,SELCODE			; target CS:EIP in protected mode
	mov edi,offs @@2
	jmp cs:rmtopmswrout		; go back to protected mode

@@2:	mov ax,rmstacklen		; restore top of real mode stack
	add rmstacktop,ax
	inc _pc_irqrmtopm		; increment IRQ RM->PM counter
	pop gs fs es ds			; restore all registers
	popad
	pop ax				; restore original AX
	iretd








; IRQ Callback
;
; Used by IRQs in real mode to process protected mode IRQ handlers.
;
;=============================================================================
irq_callback:
	cli
	pop ax
	sub ax,offs back_matrix+1
	shr ax,2			; AX = IRQ number
	pushad
	push ds es fs gs
	mov ds,cs:kernel_code

	inc _pc_irqcbrmtopm		; increment IRQCallback RM->PM counter
	mov temp_int,al
	mov edx,pmstacktop		; EDX = ESP for protected mode
	mov ebx,edx
	sub edx,pmstacklen
	cmp edx,pmstackbase		; exceeded protected mode stack space?
	jb critical_error_pm		; if yes, critical error
	mov pmstacktop,edx		; update ptr for possible reenterancy

	mov bp,ss			; save real mode SS:SP in EBP
	shl ebp,16
	mov bp,sp
	mov si,irqcallbackptr		; save ESP across mode switches
	mov dptr @callback_data[si+100h],esp
	add irqcallbackptr,4

	mov ax,SELCODE			; prot. mode DS
	mov cx,SELZERO			; prot. mode ES
	mov dx,cx			; prot. mode SS
	mov si,ax			; prot. mode CS
	mov edi,offs @@0			; prot. mode EIP
	jmp rmtopmswrout		; switch to protected mode

@@0:	movzx bx,temp_int
	shl bx,3			; BX = pointer to interrupt ##h
	pushfd				; set return eflags
	push large SELCODE		; set return CS on PM stack
	push large offs @@1		; set return EIP on PM stack
	db 66h
	jmp dword ptr irqtab_pm[bx]	; go to prot. mode interrupt handler

@@1:	mov ax,_KERNEL			; AX = real mode DS
	mov si,ax			; SI = real mode CS
	mov di,offs @@2			; DI = real mode IP
	mov bx,bp			; BX = real mode SP
	shr ebp,16
	mov dx,bp			; DX = real mode SS
	db 66h
	jmp word ptr cs:pmtormswrout	; switch to real mode

@@2:	mov eax,pmstacklen
	add pmstacktop,eax
	inc _pc_irqcbpmtorm		; increment IRQCallback PM->RM counter

	sub irqcallbackptr,4		; restore original ESP
	mov si,irqcallbackptr
	mov esp,dptr @callback_data[si+100h]

	pop gs fs es ds
	popad
	pop ax
	iret				; return from IRQ callback








;=============================================================================
;	Real mode callback actual code:
;##	pushad
;##	push 0				; if 0, callback is free
;##	push large 0
;##	mov cx,0			; load CX with callers ES
;##	push large
;##	jmp far ptr ?:?
;
callback:				; real mode callback handler
	mov ax,sp			; preserve SS:SP for callback
	push ss
	push ax
	push gs fs ds es		; preserve real mode regs for callback
	pushf				; preserve FLAGS for callback
	cli
	push cs
	pop ds

	inc _pc_cbrmtopm		; increment Callback RM->PM counter
	mov ebp,pmstacktop		; EBP = ESP for protected mode
	mov ebx,ebp			; set EBX to next stack location
	sub ebx,pmstacklen
	mov pmstacktop,ebx		; update ptr for possible reenterancy
	cmp ebx,pmstackbase		; exceeded protected mode stack space?
	jb critical_error_pm		; if yes, critical error

	xor eax,eax			; EAX = base address of SS
	mov ebx,eax
	mov ax,ss
	shl eax,4
	mov bx,sp			; EBX = current linear SS:SP
	add ebx,eax

	mov es,ds:gdtseg		; set for protected mode callback DS
	or eax,92000000h		;  base address in GDT
	mov es:[SELCALLBACK+2],eax
	mov ax,SELZERO			; DS selector for protected mode
	mov dx,ax			; SS selector = DS selector
	mov si,SELCODE			; target protected mode CS:EIP
	mov edi,offs @@0
	jmp rmtopmswrout		; go to protected mode

@@0:	mov edi,[esp+14]		; EDI -> register structure from stack
	lea esi,[esp+24]		; copy general registers from stack
	mov ecx,8			;  to register structure
	cld
	rep movs dword ptr es:[edi],dword ptr ds:[esi]

	mov esi,esp			; copy FLAGS, ES, DS, FG, and GS
	movs word ptr es:[edi],word ptr ds:[esi]
	movs dword ptr es:[edi],dword ptr ds:[esi]
	movs dword ptr es:[edi],dword ptr ds:[esi]
	lods dword ptr ds:[esi]		; EAX = real mode SS:SP from stack
	add ax,42			; adjust SP for stuff on stack
	mov es:[edi+4],eax		; put in register structure
	mov ds,cs:selcallback		; DS = callback DS selector
	sub edi,42			; EDI -> register structure
	movzx esi,ax			; ESI = old real mode SP
	xchg esp,ebp			; ESP = protected mode stack
	pushfd				; push flags for IRETD from callback
	push large cs			; push 32bit CS for IRETD
	push large offs @@1		; push 32bit EIP for IRETD
	movzx eax,word ptr [ebp+22]	; EAX = target CS of callback
	push eax			; push 32bit CS for RETF to callback
	push dword ptr [ebp+18]		; push 32bit EIP for retf
	db 66h				; 32bit RETF to callback
	retf

@@1:	cli
	push es				; DS:ESI = register structure
	pop ds
	mov esi,edi
	mov es,cs:selzero		; ES -> 0 (beginning of memory)
	movzx ebx,word ptr [esi+2Eh]	; EBX = real mode SP from structure
	movzx edx,word ptr [esi+30h]	; EDX = real mode SS from structure
	sub bx,42			; subtract size of vars to be put
	mov ebp,[esi+0Ch]		; EBP = pushed ESP from real mode
	mov bp,bx			; EBP = old high & new low word of ESP
	lea edi,[edx*4]			; EDI -> real mode base of stack
	lea edi,[edi*4+ebx]		;  of vars to be stored
	mov ecx,8			; copy general registers to stack
	cld
	rep movs dword ptr es:[edi],ds:[esi]
	mov eax,[esi+6]			; EAX = return FS and GS for real mode
	mov es:[edi],eax		; store on real mode stack for return
	mov eax,[esi+10]		; EAX = return CS:IP for real mode
	mov es:[edi+4],eax		; store on real mode stack for return
	mov ax,[esi]			; AX = return FLAGS for real mode
	mov es:[edi+8],ax		; store on real mode stack for return
	mov ax,[esi+4]			; AX = return DS for real mode
	mov cx,[esi+2]			; CX = return ES for real mode
	mov si,_KERNEL			; real mode target CS:IP
	mov di,offs @@2
	db 66h				; JMP DWORD PTR, as in 32bit offset,
	jmp word ptr cs:pmtormswrout	;  not seg:16bit offset

@@2:	mov esp,ebp			; restore total ESP, old high word
	mov eax,cs:pmstacklen		; restore top of protected mode stack
	add cs:pmstacktop,eax
	inc cs:_pc_cbpmtorm		; increment Callback PM->RM counter
	popad				; get callback return general regs
	pop fs gs			; get callback return FS and GS values
	iret				; go to callback return CS:IP


⌨️ 快捷键说明

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