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

📄 galloc.asm

📁 dos 1.0 其中包含quick basic源代码、内存管理himem emm386 发展历史
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;*
;*	COW : Character Oriented Windows
;*
;*	galloc.asm : global memory allocation

	TITLE	GALLOC - Global memory allocator

	.xlist
	include kernel.inc
	include galloc.inc
	include pbi.inc
	.list


;*****************************************************************************


sBegin	BSS
    assumes DS,DGROUP

staticW plblFailSearch,0		;* label to jump to if compact fails

sEnd	BSS

sBegin	DATA

externW <psLom>

sEnd	DATA


;*****************************************************************************


sBegin	KERNEL
    assumes CS,KERNEL
    assumes DS,NOTHING		;* DS points to MOB usually
    assumes SS,DGROUP

externNP	<gcompact,gmovebusy>		;* gcompact.asm
externNP	<galign>			;* ginterf.asm
externNP	<UnbindAll>			;* ldtunk.asm

	PUBLIC	gsplice, gjoin, gzero, gsearch, gmarkfree, gfindfree, gcheckfree
	PUBLIC	DoSearchAddMemory

SUBRS	PROC	NEAR

; Subroutine to splice in a new block into the arena after an existing block
;
;   Inputs:	ES:DI = address of existing block
;		SI = address of new block to add to arena after existing block
;		DS:DI = address of global arena information structure
;
;   Outputs:	Updated size field for old and new block
;		Updated hi_count field in global arena information structure
;
;   Destroys:	CX
;

gsplice:
	inc	[di].hi_count		; Adding new arena entry
	push	si			; save new
	push	es			; save old
	mov	cx,si			; save old.next
	xchg	ES:[di].ga_next,cx	; and old.next = new
	mov	es,cx
	mov	ES:[di].ga_prev,si	; [old old.next].prev = new
	mov	es,si
	mov	ES:[di].ga_next,cx	; new.next = old old.next
	sub	si,cx			; new.size = new.next - new - 1
	neg	si
	dec	si
	mov	ES:[di].ga_size,si
	pop	cx			; new.prev = old
	mov	ES:[di].ga_prev,cx
	mov	ES:[di].ga_owner,di	; Zero owner & handle fields
	mov	ES:[di].ga_handle,di
	mov	ES:[di].ga_sig,GA_SIGNATURE
	mov	es,cx			; ES = old
	sub	cx,ES:[di].ga_next	; old.size = old.next - old - 1
	neg	cx
	dec	cx
	mov	ES:[di].ga_size,cx
	pop	si			; Restore new
	ret


; Subroutine to join two blocks together, by removing one
;
;   Inputs:	ES:DI = address of block to remove
;		DS:DI = address of global arena information structure
;
;   Outputs:	ES:DI = address of block that pointed to the one removed, with
;			update size field and next pointer.
;		Updated hi_count field in global arena information structure
;
;   Destroys:	SI
;

gjoin:
	dec	[di].hi_count
	mov	si,ES:[di].ga_prev	; who points to this block
	mov	es,ES:[di].ga_next	; Get address of block after
	mov	ES:[di].ga_prev,si	; one we are removing.
	push	es			; Change it's back link
	mov	es,si
	pop	ES:[di].ga_next 	; and change the forward link
	sub	si,ES:[di].ga_next	; Recompute size of block
	neg	si
	dec	si
	mov	ES:[di].ga_size,si
	ret


; Subroutine to fill a block with zeros
;
;   Inputs:	BX = address of first paragraph to zero
;		CX = address of last paragraph to zero
;
;   Outputs:	BX = 0
;
;   Destroys:	CX
;

gzero:
	push	ax
	push	di
	push	es

	mov	es,bx		    ; ES = destination
	sub	bx,cx		    ; BX = #para
	neg	bx
	inc	bx
zero1:
	mov	cx,1000h
	cmp	bx,cx
	jae	zero2
	mov	cx,bx
	jcxz	zero3
zero2:
	sub	bx,cx
	shl	cx,1
	shl	cx,1
	shl	cx,1
	xor	ax,ax
	xor	di,di
	cld
	rep	stosw		; Zero it out

	mov	ax,es		; Move to next 64k block
	add	ah,10h
	mov	es,ax

	jmp	zero1
zero3:
	pop	es
	pop	di
	pop	ax
	ret


;*	* special trap routines for search failure
;*	* We will first try to compact. Then we will try to allocate some
;*	* Additonal memory.  If This fails we will then try to trash som
;*	* bound segments(for code).  Finally we fail.
;*	*
;* if we failed we will then try to allocate memory to add onto our
;*	* We will get the largest free memory.	If > predefined minimum
;*	* to add, then we will try to add this new segment into our
;*	* memory list. Note: we will continue trying to allocate memory
;*	* Until we do not get a big enough chunk.

DoSearchFail:		;* if search fails second time, give up
	pop	ax
	pop	cx
	pop	bx
	xor	ax,ax			;* failure
	ret

DoSearchUnBind:
;*	* if after compacting we still don't have enough
;*	*   if compacting for a data request => give up (DoSearchFail)
;*	*   if compacting for code => unbind any segments and try again
	pop	ax
	push	ax			;* ax = flags
	test	al,GA_ALLOCHIGH 	; Allocating from high memory?
	jz	DoSearchFail		;* give up for data
;*	* still trying code (un-bind any bound segments)
	cCall	UnbindAll
	mov	plblFailSearch,kernelOffset DoSearchFail
	jmp	do_compact




DoSearchAddMemory:
IFDEF	WINDOWS_OLD_APP
	jmp	DoSearchUnbind		;* We can't handle this case 
ELSE	; !WINDOWS_OLD_APP

	mov	bx,0ffffh		; Try to allocate 1 meg?
	mov	ah,48h
	int	21h
	cmp	bx,100h 		; Add minimum of 4k
	jc	DoSearchUnbind		; Not enough try 3rd pass

	mov	ah,48h			; Now lets allocate it
	int	21h			;
	jc	DoSearchUnbind		; Allocate now failed?

;;;;; for now we will only handle ones added to end of list.
	; see if we insert new chunk at begining, ending, or in middle
	cmp	ax,[di].hi_first	; see if before current first block
	jc	DoSearchAddMemory	 ; New lowest block
	cmp	ax,[di].hi_last 	; see if after highest
	jc	DoSearchAddMemory	; Tsr went away?
	; New highest point - most probable case.  We ran something that
	; was a TSR.  Now lets merge this memory in.  We need to create a
	; new End sentinal.  As the last ax=start, bx=lenth in paragraphs

	push	ax			;* Save original paragraph number
	test	ax,GA_ALIGN		;* see if aligned right
	jz	ok_align		;* yes
	mov	cx,ax			;* save orignal size
	add	ax,GA_ALIGN
	and	ax,GA_MASK		;* new starting position
	push	ax
	sub	ax,cx			;* see the difference
	sub	bx,ax			;* now update count of bytes
	pop	ax			;* restore new starting position
ok_align:
	mov	cx,ss:psLom		;* Need to make sure in range
	mov	es,cx			;* Use segment register.
	mov	cx,ax			; Save start postion.
	add	ax,bx			;* ax = new end
;*	* check to make sure we are within the useable limits
	cmp	ax,es:[psUseMax]
	jb	still_in_range		;* ok request
	mov	ax,es:[psUseMax]
Still_in_range:
	sub	ax,GA_ALIGN		;* Lets get right position
	and	al,LOW(GA_MASK) 	;* make even
	mov	bx,ax			;* compute new free area added
	sub	bx,cx			;*
	dec	bx			;*

;*	now	lets create a header for new free memory segment
	mov	es,cx			;* setup segment.
	mov	es:[di].ga_sig,GA_SIGNATURE ;* data segment
	mov	es:[di].ga_owner,0	;* Free memory
	mov	es:[di].ga_size,bx	;* How much free area added
	mov	es:[di].ga_flags,0
	mov	es:[di].ga_handle,di	;* no handle
	mov	es:[di].ga_next,ax	;* link to new sentinal
	mov	bx,[di].hi_last 	;* Get old high mark.
	mov	es:[di].ga_prev,bx	;* Link to old sentinal

;*	* create new sentinal
	mov	es,ax			;* setup new sentinal segment
	mov	es:[di].ga_sig,GA_ENDSIG
	mov	es:[di].ga_owner,-1	;* sentinal
	mov	es:[di].ga_size,GA_ALIGN
	mov	es:[di].ga_flags,0
	mov	es:[di].ga_handle,di	;* no handle
	mov	es:[di].ga_next,es	;* link to self
	mov	es:[di].ga_prev,cx

;*	* update Old sentinal to be	;* fixed block that cant move
	xchg	ax,[di].hi_last 	;* Setup pointer to new last object
	mov	es,ax			;* now we need to modify header
	mov	es:[di].ga_sig,GA_HOLE	;* setup as a hole.
	mov	es:[di].ga_next,cx	;* Setup next pointer to new memory object
	sub	cx,ax			;* Setup size of hole.
	dec	cx			;*
	mov	es:[di].ga_size,cx	;* size of hole
	pop	es:[di].ga_newpara	   ;* put allocation seg paragraph number


;*	* now add 2 to the number of items in the list
	add	[di].hi_count,2 	;* add new free list, and endsig

	jmp	short do_compact	; now compact using new memory
ENDIF	; WINDOWS_OLD_APP


;**********************************************************

⌨️ 快捷键说明

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