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

📄 gmem.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	xchg	ax,si		    ; Return original handle
				    ; Set back link to handle in new block
	dec	si
	mov	es,si
	mov	ES:[di].ga_handle,ax
	and	ch,GA_SEGTYPE
	mov	ES:[di].ga_flags,ch ; Copy segment type flags to ga_flags
racreate0:
	jmp	raexit
racreate1:
	jmp	rafailmem1
raokay:
	mov	si,bx
	add	bx,ax		    ; Compute address of new next header
	call	galign		    ; assuming there is room.
; Here if not trying to realloc this block to zero
; ES:0 = arena header of current block
; AX:0 = client address of current block
; CH = lock count of current block
; DX:0 = new next block, based on new requested size
; SI = new requested size of block
	mov	bx,ES:[di].ga_next  ; Get address of current next header
	cmp	dx,bx		    ; Are we growing or shrinking?
	ja	ragrow		    ; We are growing
rashrink:			    ; We are shrinking
; Here to shrink a block
; ES:0 = arena header of current block
; BX:0 = arena header of next block
; DX:0 = new next block, based on new requested size
	mov	si,dx		    ; SI = new next block
	inc	dx		    ; Test for small shrinkage
	inc	dx
	errnz	<GA_ALIGN-1>

	cmp	dx,bx		    ; Is there enough room from for free block?
	jae	raoverflow	    ; No, then no change to make
				    ; Yes, ES:DI = current block, SI=new block
	call	gsplice 	    ; splice new block into the arena
	mov	es,si		    ; ES:DI = new free block
	call	gmarkfree	    ; Mark it as free
rasame:
	mov	ax,h		    ; Return the same handle
rax:	jmp	raexit		    ; All done

raoverflow:
	test	byte ptr rflags,GA_ZEROINIT ; Zero file extension?
	jz	rasame	            ; No, continue
	mov	cx,bx		    ; Next heap header
	dec	cx		    ; Last paragraph for us
	mov	bx,si		    ; Where the new block would have started
	call	gzero		    ; zero fill extension
	jmp	short rasame

; Here to try to grow the current block
; AX:0 = client address of current block
; CH = lock count of current block
; ES:0 = arena header of current block
; BX:0 = arena header of next block
; DX:0 = new next block, based on new requested size
; SI = new requested size of block
ragrow:
	mov	al,1		    ;* first time through
ragrowagain:	;* al == 0 => don't retry
	push	es		    ; Save current block address
	mov	es,bx		    ; ES = next block address
	cmp	ES:[di].ga_owner,di ; Is next block free?
	jne	ragrow1		    ; No, can't fit it in
	sub	dx,bx		    ; Yes, compute how much of it we need
	push	si		    ; See if free block is big enough
	push	ax		    ;* save flag
	call	gcheckfree
	pop	ax
	pop	si
	jb	ragrow2		    ; No, can't fit it in
	add	dx,bx		    ; Yes, restore new next block address
	pop	cx		    ; Discard saved value (gjoin returns it)
	mov	cx,es		    ; Yes, save free block address in CX
	call	gjoin		    ; and attach to end of current block
	test	byte ptr rflags,GA_ZEROINIT ; Zero fill extension?
	jz	ranz		    ; No, continue
	mov	bx,cx		    ; Yes, BX = first paragraph to fill
	mov	cx,dx		    ; compute last paragraph to fill
	dec	cx		    ; into CX
	call	gzero		    ; zero fill extension
ranz:
	mov	bx,ES:[di].ga_next  ; Pick up new next block address
	jmp	rashrink	    ; Now shrink block to correct size

ragrow2:
	add	dx,bx		    ;* restore dx
; Here to try to move the current block (or grow fixed block in place)
; BX:0 = arena header of next block
; CH = lock count of current block
; DX:0 = new next block, based on new requested size
; (on stack) ES:0 = arena header of current block
; SI = new requested size of block
ragrow1:
	pop	es		    ; Recover current block address
	push	bx
	push	dx		    ;* save flags in case we must retry
	mov	dx,rflags	    ; get the passed in flags
	AssertReset dl,GA_DISCCODE  ;* you can not grow fixed code !
	mov	bx,GA_MOVEABLE	    ; Determine if okay to move this guy
	jcxz	ramove1 	    ; Continue if this handle not locked
	test	dx,bx		    ; Locked.  Did they say move anyway?
	jnz	ramove1 	    ; Yes, go do it
;*	* Can't move (i.e. fixed or locked)
	jmp	short ragrowfixed   ;* force grow in place
ramove1:
	or	dx,bx		    ; make sure moveable bit set
	test	h,GA_FIXED	    ; Is this a moveable handle?
	jz	ramove2 	    ; Yes, okay to move
	xor	dx,bx		    ; No, clear moveable flag in arg to gsearch
	test	rflags,bx	    ; Did they say it's okay to move?
	jnz	ramove2 	    ; Yes, proceed
ragrowfixed:
	or	al,al
	jz	rafailmem	    ;* try maximum of twice
	push	ax
	push	si
	push	es
IFDEF	REALLOC_FIXED
	mov	dx,si		    ;**** over size request M00BUG
	cCall	gfixedCompact
ELSE	; REALLOC_FIXED
	xor	dx,dx		    ; No, get size of largest free block
	call	gcompact	    ; AX = size of largest free block
ENDIF	; REALLOC_FIXED
	pop	es
	pop	si
	pop	ax
	xor	al,al		    ;* last chance
;*	* block can not be moved, but gcompact may have freed sufficient
;*	* space.
	pop	dx
	pop	bx		    ;* restore everything to look like ragrow
	jmp	ragrowagain

rafailmem:
	mov	bx,h
	test	bl,GA_FIXED
	jnz	rafail2
	mov	bx,[bx].he_address
rafail2:			    ; BX = client data address
	dec	bx
	mov	es,bx		    ; ES = arena header address
	mov	ax,es:[di].ga_size  ; AX = size of current block
	mov	es,es:[di].ga_next  ; Check following block
	cmp	es:[di].ga_owner,di ; Is it free?
	jne	rafailmem0	    ; No, continue
	add	ax,es:[di].ga_size  ; Yes, then include it as well
	inc	ax
rafailmem0:
	cmp	ax,dx		    ; Chose the larger of the two
	jbe	rafailmem1
	mov	dx,ax
rafailmem1:
	xor	ax,ax
	jmp	rax

ramove2:
	pop	ax
	pop	ax		    ;* ignore 2 saved values from ragrow1
	mov	ax,dx		    ; AX = allocation flags
	mov	bx,si		    ; BX = size of new block
	mov	cx,si		    ; CX = owner (use size for now)
	call	gsearch 	    ; Find block big enough
	jz	racantmove	    ; Cant find one, grow in place now?
	mov	si,h
	mov	cx,ax
	test	si,GA_FIXED
	jnz	ramove3
	mov	cx,si
	mov	si,[si].he_address  ; SI = old client data address
ramove3:
	dec	ax
	mov	es,ax		    ; ES = destination arena
	dec	si		    ; SI = source arena
	call	gmovebusy	    ; Call common code to move busy block
	mov	ax,cx		    ; Return new handle
raexit:
	mov	cx,ax
	mov	sp,bp
	pop	bp
	ret


racantmove:
	mov	bx,h
	test	bl,GA_FIXED
	jnz	racmove1
	mov	bx,[bx].he_address
racmove1:			    ; BX = client data address
	mov	ax,bx
	dec	bx
	mov	es,bx		    ; ES = arena header address

	mov	bx,rsize
	add	bx,ax		    ; Compute address of new next header
	call	galign		    ; assuming there is room.

	mov	bx,ES:[di].ga_next  ; Get address of current next header
	mov	es,bx		    ; ES = next block address
	cmp	ES:[di].ga_owner,di ; Is next block free?
	jne	racmove3	    ; No, try to move the current block
	sub	dx,bx		    ; Yes, compute how much of it we need
	call	gcheckfree	    ; See if free block is big enough
	jb	racmove3	    ; No, try to move the current block
	add	dx,bx		    ; Yes, restore new next block address
	mov	cx,es		    ; Yes, save free block address in CX
	call	gjoin		    ; and attach to end of current block
	test	byte ptr rflags,GA_ZEROINIT ; Zero fill extension?
	jz	racmove2	    ; No, continue
	mov	bx,cx		    ; Yes, BX = first paragraph to fill
	mov	cx,dx		    ; compute last paragraph to fill
	dec	cx		    ; into CX
	call	gzero		    ; zero fill extension
racmove2:
	mov	bx,ES:[di].ga_next  ; Pick up new next block address
	jmp	rashrink	    ; Now shrink block to correct size

racmove3:
	xor	dx,dx		    ; No, get size of largest free block
	call	gcompact
	mov	dx,ax		    ; DX = size of largest free block
	jmp	rafailmem


; GFREE - procedure to free a global object
;
;   Inputs:	DX = global memory object handle
;		CX = owner field value to match or zero if dont care
;		DS:DI = address of global heap info
;
;   Outputs:	AX = zero it successful or handle if not
;		CX = AX
;

gfree:
	push	cx
	call	gdref
	pop	dx
	jz	gf2		    ; Free handle if object discarded
	or	dx,dx
	jnz	gf3
gf1:
	call	gmarkfree	    ; No, free the object
gf2:
	call	hfree		    ; Free handle
gfx:
	mov	cx,ax
	ret
gf3:
	cmp	ES:[di].ga_owner,dx
	je	gf1
	mov	ax,-1
	jmp	short gfx


; GLOCK - procedure to increment the lock count of an object
;
;   Inputs:	BX = handle to global object
;		CX = handle table flags and lock count for moveable objects
;		DX = segment address of object
;		DS:DI = address of master object
;
;   Outputs:	Updated lock count in handle table entry and CX
;		Z flag set if count overflowed.
;

glock:
	inc	ch		    ; Increment lock count
	jz	gl2		    ; All done if overflow
	mov	[bx].he_count,ch    ; Update lock count
gl2:
	ret


; GUNLOCK - procedure to deccrement the lock count of an object
;
;   Inputs:	BX = handle to global object
;		CX = handle table flags and lock count for moveable objects
;		DX = segment address of object
;		DS:DI = address of master object
;
;   Outputs:	CX = 0 if handle already unlocked. non-zero o.w.
;		Updated lock count in handle table entry and CX
;		Z flag set if count underflowed.
;

gunlock:
	dec	ch		    ; Decrement usage count
	cmp	ch,0FFh-1	    ; ff -> fe, 0 -> ff
	jae	gul1		    ; Return if pinned, or was already zero
	dec	[bx].he_count	    ; Non-zero update lock count
	jnz	gul2		    ; All done if still non-zero
	test	cl,GA_DISCARDABLE   ; Is this a discardable handle?
	jz	gul1		    ; No, all done
gul1:
	xor	cx,cx
gul2:
	ret			    ; Non-zero lock count. Return true


SUBRS	ENDP

sEnd	KERNEL

	END

⌨️ 快捷键说明

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