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

📄 int31h.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	mov [esi+04h],eax		; set this block as free
	lea edi,[esi+eax+10h]		; get address of next block
	cmp edi,cs:mem_top		; check if at top of memory
	jae @@0
	mov edx,[edi+04h]		; get size of next block
	btr edx,31			; check if block next to us is free
	jc @@0				; if not, jump
	lea edx,[eax+edx+10h]		; calculate total size (this+hdr+next)
	cmp edx,ebx			; check if enough
	jb @@0				; if not, jump
	mov eax,edx			; set this size = (this + next)
	mov [esi+04h],eax		; link this and next blocks
	jmp int31_allocblock		; and go to the allocation routine

@@0:	mov edi,cs:mem_ptr		; get pointer to memory
@@1:	mov edx,[edi+04h]		; get block size
	btr edx,31			; check if memory block is used
	jc @@2				; if yes, jump
	cmp edx,ebx			; check if block is large enough
	jae @@3				; if yes, allocate block
@@2:	lea edi,[edi+edx+10h]		; load address of next memory block
	cmp edi,cs:mem_top		; check if at top of memory
	jb @@1				; if not, loop
	bts eax,31			; set this block as used
	mov [esi+04h],eax		; restore state of this block
	jmp int31fail8013		; fail: not enough memory

@@3:	push esi edi
	mov ecx,eax
	shr ecx,2
	add esi,10h
	add edi,10h
	rep movs dword ptr es:[edi],ds:[esi]
	mov cl,al
	and cl,3
	rep movs byte ptr es:[edi],ds:[esi]
	pop edi esi
	call int31_linkfreeblocks
	mov esi,edi
	mov eax,edx
	jmp int31_allocblock		; and go to the allocation routine


;=============================================================================
int31050A:
	shl esi,16			; convert SI:DI to ESI
	mov si,di
	call int31_checkifmemavail
	call int31_checkblocks
	call int31_checkhandle
	mov ebx,[esi+04h]		; check if block is used
	btr ebx,31
	jnc int31fail8023
	add esi,10h
	xchg ebx,esi
	mov cx,bx
	shr ebx,16
	mov di,si
	shr esi,16
	jmp int31oksinoax





;-----------------------------------------------------------------------------
int31_checkifmemavail:			; check if memory had been allocated
	pop bp
	push eax
	mov eax,cs:mem_ptr
	or eax,cs:mem_free
	pop eax
	jz int31fail8013
	jmp bp


;-----------------------------------------------------------------------------
int31_checkblocks:			; check if memory had been overwritten
	test cs:pm32_mode,00100000b
	jz @@done
	push eax esi
	mov esi,cs:mem_ptr
@@1:	test si,000Fh			; blocks must be para aligned
	jnz @@err
	mov eax,12345678h		; header id
	cmp eax,[esi+00h]		; if no header_id at block start
	jnz @@err			; then signal error
	cmp eax,[esi+0Ch]		; if no header_id at block end
	jnz @@err			; then signal error
	mov eax,[esi+04h]		; get block size
	btr eax,31			; reset the used flag
	lea esi,[esi+eax+10h]		; load address of next memory block
	cmp esi,cs:mem_ptr
	jb @@err
	cmp esi,cs:mem_top		; check if at top of memory
	ja @@err
	jb @@1				; if not, loop
	pop esi eax
@@done:	ret

@@err:	mov ds,cs:seldata
	xor eax,eax
	mov mem_ptr,eax			; set to zero to prevent looping error
	mov mem_free,eax		; when exiting
	mov al,83h
	jmp dword ptr client_call


;-----------------------------------------------------------------------------
int31_checkhandle:
	pop bp				; check for valid handle in ESI
	cmp esi,cs:mem_ptr
	jb @@1
	cmp esi,cs:mem_top
	ja @@1
	mov eax,12345678h
	cmp eax,[esi+00h]
	jnz @@1
	cmp eax,[esi+0Ch]
	jnz @@1
	jmp bp
@@1:	jmp int31fail8023		; fail: invalid handle





;-----------------------------------------------------------------------------
int31_testbxcxtoebx:			; convert BX:CX to EBX
	pop bp
	shl ebx,16
	mov bx,cx
	test ebx,ebx
	jz int31fail8021		; BX:CX cannot be zero
	add ebx,0Fh			; align EBX on para boundary
	and bl,0F0h
	bt ebx,31
	jc int31fail8021		; cannot allocate that much memory
	jmp bp


;-----------------------------------------------------------------------------
int31_getfreemem:
	xor eax,eax			; reset free memory size
	xor ecx,ecx
	mov esi,cs:mem_ptr		; get pointer to memory
@@1:	mov edx,[esi+04h]		; get block size
	btr edx,31			; check if memory block is used
	jc @@2				; if yes, jump
	add ecx,edx
	cmp eax,edx			; pick largest value
	ja @@2
	mov eax,edx
@@2:	lea esi,[esi+edx+10h]		; load addres of next memory block
	cmp esi,cs:mem_top		; check if at top of memory
	jb @@1				; if not, loop
	ret


;-----------------------------------------------------------------------------
int31_allocblock:
	mov ecx,12345678h
	movzx edx,cs:id32_process_id
	sub eax,ebx			; nextsize=actualsize-allocsize
	sub eax,10h			; is nextsize<16 (header size)
	jb @@1				; if yes, do not create next block
	lea edi,[esi+ebx+10h]		; EDI = ptr to next block
	mov [edi+00h],ecx		; header ID1
	mov [edi+04h],eax		; set next block as free/size
	mov [edi+08h],edx		; process_ID
	mov [edi+0Ch],ecx		; header ID2

@@1:	bts ebx,31			; set this block as used
	mov [esi+00h],ecx		; header ID1
	mov [esi+04h],ebx		; store this block size in header
	mov [esi+08h],edx		; process_ID
	mov [esi+0Ch],ecx		; header ID2
	call int31_linkfreeblocks

	lea ebx,[esi+10h]		; EBX = ptr to memory block  (-header)
	mov cx,bx
	shr ebx,16
	mov di,si
	shr esi,16
	jmp int31oksinoax


;-----------------------------------------------------------------------------
int31_linkfreeblocks:
	pushad
	mov edi,cs:mem_ptr		; EDI = ptr to 1st block handle
	mov ebp,cs:mem_top

	mov eax,[edi+04h]		; get 1st block size
	btr eax,31
	lea esi,[edi+eax+10h]		; ESI = ptr to 2nd block handle
	cmp esi,ebp			; check if at top of memory
	jae @@done			; if yes, done
	mov esi,edi			; ESI=EDI = ptr to 1st block

@@1:	mov eax,[esi+04h]		; get block size
	btr eax,31			; check if block is used
	jc @@4				; if yes, jump

	xor ebx,ebx			; reset amount of free block memory
	xor ecx,ecx			; reset number of free blocks in raw
	mov edi,esi			; remember addr of first free block
	jmp @@3

@@2:	add ecx,10h			; increment number of free blocks
	mov eax,[esi+04h]		; get block size
	btr eax,31			; check if block is free
	lea ebx,[eax+ebx]		; amount of free memory encountered
	jnc @@3				; if yes, jump
	sub ebx,eax
	sub ecx,10h
	add ebx,ecx
	add [edi+04h],ebx
	jmp @@4

@@3:	lea esi,[esi+eax+10h]		; calculate address of next block
	cmp esi,ebp			; check if at top of memory
	jb @@2				; if not, loop
	add ebx,ecx
	add [edi+04h],ebx
	jmp @@done

@@4:	lea esi,[esi+eax+10h]		; calculate address of next block
	cmp esi,ebp			; check if at top of memory
	jb @@1				; if not, loop

@@done:	popad
	ret






;=============================================================================
; VIRTUAL MEMORY FUNCTIONS (not supported)
;=============================================================================

;=============================================================================
int310600:
int310601:
int310602:
int310603:
int310702:
int310703:
	jmp int31ok


;=============================================================================
int310604:
	xor bx,bx
	mov cx,1000h
	jmp int31okbx






;=============================================================================
; PHYSICAL MEMORY MAPPING FUNCTIONS
;=============================================================================

;=============================================================================
int310800:				; physical memory mapping
	shl ebx,16			; convert BX:CX to EBX
	shl esi,16			; convert SI:DI to ESI
	mov bx,cx
	mov si,di
	cmp ebx,100000h			; check if mapping under 1MB limit
	jb int31fail8021		; if yes, error
	test esi,esi			; check if size is zero
	jz int31fail8021		; if yes, error
	cmp cs:pmodetype,2		; check if system is VCPI
	jz int310800v			; if yes, do VCPI memory mapping
	jmp int31ok			; if under raw/XMS, do nothing


int310800v:
	cmp cs:pm32_maxfpages,0		; check if any linear memory avail.
	jz int31fail8012		; if not, signal error 8012h

	push ds
	pop es
	mov edi,cs:phystablebase	; get base of pagetables
@@0:	mov eax,ebx			; EAX = physical address
	lea ecx,[esi+0FFFh]		; ECX = size of memory to map
	and ax,0F000h
	shr ecx,12
	mov edx,edi
@@1:	cmp edi,cs:phystabletop		; are there any pages mapped left
	jae @@3				; no, go on with mapping

	mov ebp,[edi]
	and bp,0F000h
	cmp eax,ebp			; check if page already mapped
	jz @@2				; if yes, go to check next page
	add edi,4			; increment pointer into pagetables
	jmp @@0				; loop

@@2:	add edi,4			; increment pointer into pagetables
	add eax,4096
	dec ecx				; decrement amount of pages checked
	jnz @@1				; if there are more left, loop
	mov eax,ebx
	and ax,0F000h
	sub ebx,eax
	jmp @@done			; region already mapped, we are done

@@3:	mov edi,cs:phystablebase	; get base of pagetables
	mov ecx,cs:phystabletop		; get number of available pagetables
	sub ecx,edi
	shr ecx,2			; convert to 4KB pages
	mov eax,ebx
	and ax,0F000h
	lea ebp,[ebx+esi+0FFFh]		; EBP = number of required 4KB pages
	sub ebp,eax
	shr ebp,12

@@4:	test ecx,ecx			; check if no linear space left
	jz int31fail8021		; if yes, error
	xor eax,eax
	repne scas dword ptr es:[edi]	; scan for first free page
	lea edx,[edi-4]			; EDX = first free page address
	repe scas dword ptr es:[edi]	; scan for amount of free pages
	mov eax,edi
	sub eax,edx
	shr eax,2			; EAX = free pages available
	cmp eax,ebp			; check if enough free pages
	jb @@4				; no, must loop

	mov eax,ebx			; EAX = physical address
	and ax,0F000h
	sub ebx,eax
	mov edi,edx			; EDI = address of first free page
	mov ecx,ebp
	mov al,07h			; set page as user/writeable/present
	cmp cs:cputype,3		; check if CPU is 486+
	jbe @@loop			; if not, jump
	mov al,1Fh			; set PCD and PWT bits (no page cache)

@@loop:	stos dword ptr es:[edi]		; map one 4KB page
	add eax,4096			; go for next page
	loop @@loop			; loop until no pages left
	or byte ptr [edx+1],2		; mark start of mapped block
	or byte ptr [edi-3],4		; mark end of mapped block

@@done:	sub edx,cs:phystablebase
	shl edx,10
	add edx,ebx

	mov [esp+18h],dx
	shr edx,16
	or dx,8000h
	mov [esp+10h],dx

	mov eax,cs:vcpi_cr3
	mov cr3,eax
	xor eax,eax
	mov cr2,eax
	jmp int31ok


;=============================================================================
int310801:
	cmp cs:pmodetype,2
	jz int310801v
	jmp int31ok			; if under raw/XMS, do nothing


int310801v:
	cmp cs:pm32_maxfpages,0		; check if any linear memory avail.
	jz int31fail8012		; if not, signal error 8012h

	and bx,7FFFh
	shl ebx,16
	mov bx,cx
	shr ebx,10
	and bl,0FCh

	add ebx,cs:phystablebase
	cmp ebx,cs:phystablebase	; check if addr is in range
	jb int31fail8025
	cmp ebx,cs:phystabletop
	jae int31fail8025
	test byte ptr [ebx+1],2
	jz int31fail8025

@@loop:	xor eax,eax			; clear page table entries
	xchg eax,[ebx]
	add ebx,04h
	test ah,04h
	jz @@loop

@@1:	mov eax,cs:vcpi_cr3
	mov cr3,eax
	xor eax,eax
	mov cr2,eax
	jmp int31ok






;=============================================================================
; FPU RELATED FUNCTIONS
;=============================================================================

;=============================================================================
int310E00:
	movzx ax,cs:fputype		; get FPU type
	shl ax,4
	smsw dx
	test dl,00000100b		; check EM bit
	jz @@1
	or al,00000010b
@@1:	test al,0F0h
	jz @@2
	or al,00000100b
@@2:	or al,cs:virtualfpu	; put virtual FPU flags in AX
	jmp int31okax


;=============================================================================
int310E01:
	mov ds,cs:seldata
	and bl,00000011b
	mov virtualfpu,bl
	smsw ax
	test bl,00000010b
	jz @@1
	or al,00000100b
	jmp @@2
@@1:	and al,11111011b
@@2:	lmsw ax
	jmp int31ok


;=============================================================================
int31EEFF:
	add esp,26h			; adjust stack
	pop ds				; restore DS
	mov eax,'D32A'
	push cs
	pop es
	mov ebx,offs $+2		; points to itself
	mov ch,cs:pmodetype
	mov cl,cs:cputype
	mov dx,cs:client_version
	jmp int31oknopop



⌨️ 快捷键说明

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