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

📄 int31h.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	mov word ptr ds:[edi+ebx+2],dx	; low word of 32bit linear address
	mov byte ptr ds:[edi+ebx+4],cl	; high word of 32bit linear address
	mov byte ptr ds:[edi+ebx+7],ch
	jmp int31ok			; return ok


;=============================================================================
int310008:				; set segment limit
	call int31testsel		; test for valid selector BX
	cmp cx,0Fh			; is limit greater than 1M?
	jbe @@1				; if not, jump

	or dx,0FFFh			; auto-adjust limit
	shrd dx,cx,12			; DX = low 16 bits of page limit
	shr cx,12			; CL = high 4 bits of page limit
	or cl,80h			; set granularity bit in CL

@@1:	mov word ptr ds:[edi+ebx],dx	; put low word of limit
	and byte ptr ds:[edi+ebx+6],50h	; mask off G and high nibble of limit
	or byte ptr ds:[edi+ebx+6],cl	; put high nibble of limit
	jmp int31ok			; return ok


;=============================================================================
int310009:				; set descriptor access rights
	call int31testsel		; test for valid selector BX
	call int31testaccess		; test access bits in CX

	or ch,10h			; set AVL bit, descriptor used
	and ch,0D0h			; mask off low nibble of CH
	and byte ptr ds:[edi+ebx+6],0Fh	; mask off high nibble access rights
	or byte ptr ds:[edi+ebx+6],ch	; or in high access rights byte
	mov byte ptr ds:[edi+ebx+5],cl	; put low access rights byte
	jmp int31ok			; return ok


;=============================================================================
int31000A:				; create alias descriptor
	call int31testsel		; test for valid selector BX

	xor ax,ax			; allocate descriptor
	mov cx,1
	int 31h
	jc int31fail8011		; if failed, descriptor unavailable

	push ax				; preserve allocated selector
	push ds				; copy descriptor and set type data
	pop es
	movzx edi,ax			; EDI = target selector
	mov esi,cs:gdtbase		; ESI -> GDT
	add edi,esi			; adjust to target descriptor in GDT
	add esi,ebx			; adjust to source descriptor in GDT

	movs dword ptr es:[edi],ds:[esi]; copy descriptor
	lods dword ptr ds:[esi]
	mov ah,92h			; set descriptor type - R/W up data
	stos dword ptr es:[edi]
	pop ax				; restore allocated selector
	jmp int31okax			; return ok, with AX


;=============================================================================
int31000B:				; get descriptor
	call int31testsel		; test for valid selector BX
	lea esi,[edi+ebx]		; ESI -> descriptor in GDT
	mov edi,[esp]			; get EDI buffer ptr from stack
	movs dword ptr es:[edi],ds:[esi]; copy descriptor
	movs dword ptr es:[edi],ds:[esi]
	jmp int31ok			; return ok


;=============================================================================
int31000C:				; set descriptor
	call int31testsel		; test for valid selector BX
	mov esi,[esp]			; ESI = EDI buffer ptr from stack
	mov cx,es:[esi+5]		; get access rights from descriptor
	call int31testaccess		; test access bits in CX

	push ds				; swap DS and ES, target and source
	push es
	pop ds
	pop es

	add edi,ebx			; adjust EDI to descriptor in GDT
	movs dword ptr es:[edi],ds:[esi]; copy descriptor
	lods dword ptr ds:[esi]
	or al,10h			; set descriptor AVL bit
	stos word ptr es:[edi]
	jmp int31ok			; return ok


;=============================================================================
int31000E:				; get multiple descriptors
	mov ax,000Bh			; function 000bh, get descriptor
	jmp int31000EF			; go to common function


;=============================================================================
int31000F:				; set multiple descriptors
	mov ax,000Ch			; function 000ch, set descriptor

int31000EF:				; common to funcions 000eh and 000fh
	test cx,cx			; if CX = 0, return ok immediately
	jz int31ok

	mov dx,cx			; DX = number of descriptors
	xor cx,cx			; CX = successful counter
@@l0:	mov bx,es:[edi]			; BX = selector to get
	add edi,2
	int 31h				; get/set descriptor
	jc int31failcx			; if error, fail with AX and CX

	add edi,8			; increment descriptor ptr
	inc cx				; increment successful copy counter
	dec dx				; decrement loop counter
	jnz @@l0			; if more descriptors to go, loop
	jmp int31ok			; return ok






;=============================================================================
; DOS MEMORY FUNCTIONS
;=============================================================================

;=============================================================================
int310100:				; allocate DOS memory block
	mov ah,48h			; DOS alloc memory function
	call int31010x_f2		; allocate memory
	jc int31failbx			; if fail, exit with AX=err, BX=maxmem

	mov dx,ax			; DX=segment of DOS memory block
	xor ax,ax			; allocate descriptor
	mov cx,1
	int 31h
	jnc @@1
	mov ah,49h			; if error allocating descriptor
	call int31010x_f2		; free what was allocated
	jmp int31fail8011		; and exit with error 8011h

@@1:	mov [esp+14h],ax		; set selector in DX
	mov [esp+1Ch],dx		; set base address in AX
	mov bx,ax
	mov cx,dx
	shl dx,4
	shr cx,12
	mov ax,0007h			; set selector base
	int 31h

	mov cx,0092h			; set access rights
	mov al,09h
	int 31h
	jmp int31010x			; set selector size


;=============================================================================
int310101:				; free DOS block memory
	mov ah,49h
	mov si,dx			; preserve DX = selector
	call int31010x_f1
	jc int31failax
	mov bx,si			; restore selector in BX
	jmp int310001


;=============================================================================
int310102:				; resize DOS block memory
	mov ah,4Ah
	mov si,dx			; preserve DX = selector
	call int31010x_f1
	jc int31failbx
	mov bx,si			; restore selector in BX

int31010x:
	movzx edx,word ptr [esp+10h]	; get original size
	shl edx,4			; convert para to bytes
	dec edx				; limit=size-1
	shld ecx,edx,16
	mov ax,0008h			; set limit
	int 31h
	jmp int31ok


;-----------------------------------------------------------------------------
int31010x_f1:
	pop bp
	push ax bx
	mov bx,dx		; BX = selector
	mov ax,0006h		; get base
	int 31h
	pop bx ax
	jc int31failax
	shrd dx,cx,4		; adjust CX:DX to segment value
	push bp

int31010x_f2:
	xor cx,cx
	push cx			; set real mode SS:SP
	push cx
	sub esp,10
	push dx			; set real mode ES
	push cx			; set real mode flags
	pushad			; set real mode registers
	push ss
	pop es
	mov edi,esp
	mov bl,21h
	mov ax,0300h
	int 31h
	mov bx,[esp+10h]	; get BX from structure
	mov ax,[esp+1Ch]	; get AX from structure
	lea esp,[esp+32h]
	pop bp
	jc int31failax		; if error, fail
	bt word ptr [esp-14h],0
	jmp bp






;=============================================================================
; INTERRUPT FUNCTIONS
;=============================================================================

;=============================================================================
int310200:				; get real mode interrupt vector
	movzx ebx,bl			; EBX = BL (interrupt number)
	mov dx,[ebx*4+0]		; load real mode vector offset
	mov cx,[ebx*4+2]		; load real mode vector segment
	jmp int31okdx			; return ok, with AX, CX, DX


;=============================================================================
int310201:				; set real mode interrupt vector
	mov ebp,dr7
	xor eax,eax			; reset null-ptr protection
	mov dr7,eax
	movzx ebx,bl			; EBX = BL (interrupt number)
	mov [ebx*4+0],dx		; set real mode vector offset
	mov [ebx*4+2],cx		; set real mode vector segment
	mov dr7,ebp
	jmp int31ok			; return ok


;=============================================================================
int310202:				; get protected mode exception handler
	mov ds,cs:seldata
	cmp bl,20h			; must be in range 00-1Fh
	jae int31fail8021		; invalid value

	xor cx,cx
	xor edx,edx
	cmp bl,10h			; if interrupt not in range 00-0Fh
	jae @@done			; return 0000:00000000h
	test pm32_mode,00000010b	; if no internal exception handling
	jz @@0				; then read as is
	call checkint
	jz @@1

@@0:	movzx ebx,bl
	shl ebx,3			; adjust for location in IDT
	add ebx,idtbase			; add base of IDT
	mov ds,selzero
	mov edx,dword ptr [ebx+4]	; get high word of offset
	mov dx,word ptr [ebx+0]		; get low word of offset
	mov cx,word ptr [ebx+2]		; get selector
	jmp @@done

@@1:	bt excset_pm,bx			; check if EXC is installed
	lea edx,exc_matrix[ebx*4]	; load default EIP
	mov cx,SELCODE			; load default CS
	jnc @@done			; if EXC not installed, then done
	mov edx,dptr exctab_pm[ebx*8+0]	; get EIP
	mov cx,wptr exctab_pm[ebx*8+4]	; get CS
@@done:	mov ax,[esp+28]
	jmp int31okedx			; return ok, with AX, CX, EDX


;=============================================================================
int310203:				; set protected mode exception handler
	xchg bx,cx			; swap int number with int selector
	call int31testsel		; test for valid selector BX
	xchg bx,cx

	mov ds,cs:seldata
	cmp bl,20h			; must be in range 00-1Fh
	jae int31fail8021		; invalid value
	cmp bl,10h			; only 16 exceptions are supported
	jae @@done
	movzx ecx,cx
	test pm32_mode,00000010b	; if no internal exception handling
	jz @@0				; then set as is
	call checkint
	jz @@1

@@0:	movzx ebx,bl
	shl ebx,3			; adjust for location in IDT
	add ebx,idtbase			; add base of IDT
	mov ds,selzero
	mov word ptr [ebx+0],dx		; set low word of offset
	shr edx,16
	mov word ptr [ebx+6],dx		; set high word of offset
	mov word ptr [ebx+2],cx		; set selector
	jmp @@done

@@1:	bts excset_pm,bx		; prepare and set installed bit
	mov dptr exctab_pm[ebx*8+0],edx	; set EIP
	mov wptr exctab_pm[ebx*8+4],cx	; set CS
	cmp cx,SELCODE			; if selector <> kernel selector
	jnz @@done			; then we are done
	xor eax,eax
	btr excset_pm,bx		; reset installed bit
	mov dptr exctab_pm[ebx*8+0],eax	; reset EIP
	mov wptr exctab_pm[ebx*8+4],ax	; reset CS
@@done:	jmp int31ok			; return ok


;=============================================================================
int310204:				; get protected mode interrupt vector
	mov ds,cs:seldata
	test pm32_mode,00000010b	; if no internal exception handling
	jz @@0				; then read as is
	call checkint			; check if one of IRQs
	jz @@1				; if one of IRQs, read from buffer

@@0:	movzx ebx,bl
	shl ebx,3			; adjust for location in IDT
	add ebx,idtbase			; add base of IDT
	mov ds,selzero
	mov edx,dword ptr [ebx+4]	; get high word of offset
	mov dx,word ptr [ebx+0]		; get low word of offset
	mov cx,word ptr [ebx+2]		; get selector
	jmp @@done

@@1:	bt irqset_pm,si			; check if IRQ is installed
	jnc @@2				; if not, return standard handler
	test al,0F0h			; check if IRQ is above INT 00-0Fh
	jnz @@0				; if yes, read as is
	mov edx,dptr irqtab_pm[esi*8+0]	; get EIP
	mov cx,wptr irqtab_pm[esi*8+4]	; get CS
	jmp @@done
@@2:	lea edx,std_matrix[esi*4]	; load standard EIP
	mov cx,SELCODE			; load standard CS
@@done:	mov ax,[esp+28]
	jmp int31okedx			; return ok, with AX, CX, EDX


;=============================================================================
int310205:				; set protected mode interrupt vector
	xchg bx,cx			; swap int number with int selector
	call int31testsel		; test for valid selector BX
	xchg bx,cx

	mov ds,cs:seldata
	mov es,selzero
	movzx ecx,cx			; ECX = CX (selector)

	test pm32_mode,00000010b	; if no internal exception handling
	jz @@0				; then set as is
	call checkint			; check if one of IRQs
	jz @@1				; if one of IRQs, install in buffer
	cmp bl,1Bh			; process special interrupts
	jz @@1Bh
	cmp bl,1Ch
	jz @@1Ch
	cmp bl,23h
	jz @@23h
	cmp bl,24h
	jz @@24h

@@0:	movzx ebx,bl
	shl ebx,3			; adjust for location in IDT
	add ebx,idtbase			; add base of IDT
	mov word ptr es:[ebx+0],dx	; set low word of offset
	shr edx,16
	mov word ptr es:[ebx+6],dx	; set high word of offset
	mov word ptr es:[ebx+2],cx	; set selector
	jmp @@done

@@1:	cmp cx,SELCODE			; check if restoring IRQ
	jnz @@2				; if not, jump
	btr irqset_rm,si		; reset IRQ installed bit (RM)
	btr irqset_pm,si		; reset IRQ installed bit (PM)
	mov ebp,irqtab_rm[esi*4]	; restore real mode interrupt
	mov es:[ebx*4],ebp
	test al,0F0h			; check if IRQ above INT 00-0Fh
	jnz @@0				; if yes, restore prot. mode IRQ
	xor eax,eax
	mov dptr irqtab_pm[esi*8+0],eax	; reset EIP
	mov wptr irqtab_pm[esi*8+4],ax	; reset CS
	jmp @@done

@@2:	bts irqset_rm,si		; set IRQ installed bit (RM)
	bts irqset_pm,si		; set IRQ installed bit (PM)
	mov di,_KERNEL
	shl edi,16
	lea ebp,back_matrix[esi*4]	; get address of real mode IRQ handler
	add ebp,edi
	mov es:[ebx*4],ebp		; install real mode IRQ callback
	mov dptr irqtab_pm[esi*8+0],edx	; install EIP (into IRQ buffer)
	mov wptr irqtab_pm[esi*8+4],cx	; install CS (into IRQ buffer)
	test al,0F0h			; check if IRQ above INT 00-0Fh
	jnz @@0				; if yes, install as is
@@done:	jmp int31ok			; return ok

@@1Bh:	cmp cx,SELCODE			; install real mode INT 1Bh callback
	mov eax,newint1Bh
	jnz @@1Bh0
	mov eax,oldint1Bh
@@1Bh0:	mov es:[4*1Bh],eax
	jmp @@0

@@1Ch:	cmp cx,SELCODE			; install real mode INT 1Ch callback
	mov eax,newint1Ch
	jnz @@1Ch0
	mov eax,oldint1Ch
@@1Ch0:	mov es:[4*1Ch],eax
	jmp @@0

@@23h:	cmp cx,SELCODE			; install real mode INT 23h callback
	mov eax,newint23h
	jnz @@23h0
	mov eax,oldint23h
@@23h0:	mov es:[4*23h],eax
	jmp @@0

@@24h:	cmp cx,SELCODE			; install real mode INT 24h callback
	mov eax,newint24h
	jnz @@24h0
	mov eax,oldint24h
@@24h0:	mov es:[4*24h],eax
	jmp @@0



;=============================================================================
int310900:				; get and disable interrupt state
	add esp,26h			; adjust stack
	pop ds				; restore DS
	btr word ptr [esp+8],9		; test and clear IF bit in EFLAGS
	setc al				; set AL = carry (IF flag from EFLAGS)
	jmp int31oknopop                ; return ok, dont pop registers


;=============================================================================
int310901:				; get and enable interrupt state
	add esp,26h			; adjust stack
	pop ds				; restore DS
	bts word ptr [esp+8],9		; test and set IF bit in EFLAGS
	setc al				; set AL = carry (IF flag from EFLAGS)
	jmp int31oknopop		; return ok, dont pop registers


;=============================================================================
int310902:				; get interrupt state
	add esp,26h			; adjust stack
	pop ds				; restore DS
	bt word ptr [esp+8],9		; just test IF bit in EFLAGS

⌨️ 快捷键说明

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