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

📄 gmem.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;*
;*	CW : Character Windows
;*
;*	
	TITLE	GMEM - Register interface to global memory allocator

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


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

;*	* low level procs
externNP    <halloc,hfree,hdref>	    ; HANDLE.ASM
externNP    <gsplice,gjoin,gzero>	    ; GALLOC.ASM
externNP    <gsearch,gmarkfree,gcheckfree>  ; GALLOC.ASM
externNP    <gmovebusy,gcompact>	    ; GCOMPACT.ASM
externNP    <gnotify>			    ; GINTERF.ASM
IFDEF	REALLOC_FIXED
externNP    <gfixedCompact>		    ; GFIXCOMP.ASM
ENDIF	; REALLOC_FIXED

	PUBLIC	galign, gdref, ghandle, galloc, grealloc
	PUBLIC	gfree, glock, gunlock

SUBRS	PROC	NEAR

; GALIGN - procedure to align the size request for a global item to
; the next high valid paragraph boundary.
;
;   Input:	BX = #paras
;		Carry flag set if #paras overflowed.
;
;   Output:	DX = #paras aligned to next higher multiple of 4
;
galign: jc	align1		    ; Overflow occur?
	lea	dx,[bx+GA_ALIGN]    ; No, add alignment amount
	and	dl,GA_MASK	    ; ...modulo alignment boundary
	cmp	dx,bx		    ; Test for overflow
	jb	align1		    ; Yes, continue
	ret
align1: mov	dx,GA_MASK	    ; Return largest possible size
	ret


; GDREF - procedure to dereference a global handle.
;
;   Inputs:	DX = handle
;
;   Outputs:	ES:DI = address of arena header
;		AX = address of client data
;		CH = lock count or zero for fixed objects
;		SI = handle table entry address or zero for fixed objects
;		Z flag set if NULL handle or AX = 0
;

gdref:
	xor	cx,cx			; Zero lock count
	mov	ax,dx			; Return handle if fixed object
	test	al,GA_FIXED		; Is it moveable?
	jz	dref3			; Yes, go dereference handle
	xor	si,si			; Set SI to zero for fixed objects
dref1:
	or	ax,ax			; No, were we passed NULL?
	jz	dref2			; Yes, then all done
	mov	bx,ax			; No, return ES:DI pointing
	dec	bx
	mov	es,bx			; ...to arena header
	cmp	ES:[di].ga_sig,GA_SIGNATURE ; Return error if, invalid sig.
	jne	dref4
	cmp	ES:[di].ga_handle,si	    ; Handle mismatch
	jne	dref4
	cmp	ES:[di].ga_owner,di	    ; or free block
	je	dref4
dref2:					; Otherwise return with Z flag clear
	ret
dref3:
	mov	si,dx
	call	hdref	    ; Get true address in AX and lock count in CH
	jnz	dref1	    ; Compute arena header if valid true address
	mov	bx,[si].he_address	; Return owner of discarded object
dref4:					; in BX
	xor	ax,ax
	ret

;
; GHANDLE - procedure return the handle for a global segment.
;
;   Inputs:	AX = handle or segment address parameter
;		DS:DI = master object segment address
;
;   Outputs:	AX = handle or zero if invalid segment address
;		Z flag set if DX is zero.  O.W. Z flag reset and
;		BX = pointer to handle table entry
;		CX = lock count and flags for moveable object
;		DX = segment address or zero if discarded or invalid handle
;		ES:DI = arena header of block
;
;   Destroys:	ES,BX
;

ghandle:
	mov	bx,ax			; Compute address of arena header
	test	bl,GA_FIXED		; Fixed?
	jnz	gh0			; Yes, have segment address then
	or	bx,bx			; Null handle?
	jz	gh1			; Yes, return null
	test	bl,2			; Valid moveable handle?
	jz	gh1			; No, return null
	mov	bx,ds:[di].hi_htable	; Get base of handle table
	cmp	ax,bx			; Handle pointer before it?
	jbe	gh1			; Yes, return null
	mov	cx,ds:[bx].ht_count	; Get size of handle table
	shl	cx,1
	shl	cx,1
	add	bx,cx
	cmp	ax,bx			; Handle pointer after it?
	jae	gh1			; Yes, return null
	mov	bx,ax
	mov	cx,word ptr [bx].he_flags
	inc	cx			; Free handle?
	jz	gh1			; Yes, return null
	dec	cx
	test	cl,HE_DISCARDED 	; No, discarded?
	jnz	gh3			; Yes, then no segment address
	mov	ax,ds:[bx].he_address	; No, convert handle to
	mov	bx,ax			; segment address
gh0:
	dec	bx
	cmp	ds:[di].hi_first,bx	; Error if points outside arena
	jae	gh1
	cmp	ds:[di].hi_last,bx
	jbe	gh1
	mov	es,bx
	cmp	ES:[di].ga_sig,GA_SIGNATURE
	jne	gh1			; Error if invalid signature byte
	cmp	ES:[di].ga_owner,di
	je	gh1			; Error if free segment
	mov	bx,ES:[di].ga_handle	; Get back pointer to handle
	or	bx,bx
	jz	ghx			; Return seg parameter if not moveable
	cmp	DS:[bx].he_address,ax	; Does handle point to segment?
	jne	gh1			; No, return error
gh0a:
	mov	cx,word ptr [bx].he_flags
	errnz	<2-he_flags>
	errnz	<3-he_count>
	mov	dx,ax			; Return segment address in DX
	or	dx,dx			; Clear Z flag
	mov	ax,bx			; Yes, return handle
	ret				; Return
gh1:	xor	ax,ax
ghx:	xor	cx,cx
	mov	dx,ax
	ret
gh3:
	xor	ax,ax
	test	cl,HE_SWAPPED		; Discarded, is it swapped?
	jz	gh0a			; No, return NULL

	jmp	short gh1		;* all done


; GALLOC - procedure to allocate global memory.
;
;   Inputs:	AX = allocation flags
;		BX = #paragraphs
;		CX = owner field
;		DS:DI = address of global heap info
;
;   Outputs:	AX = handle to object or zero
;		BX = size of largest free block if AX = 0
;		CX = AX
;

galloc:
	or	bx,bx			; Allocating zero size?
	jnz	ga1			; No, continue
	xchg	ax,cx			; AX = owner, CX = flags
	test	cl,GA_MOVEABLE		; Yes, moveable?
	jz	gaerr			; No, return error (AX = 0)
	push	cx			; save flags
	call	halloc			; and allocate handle for owner
	pop	dx			; restore flags
	jcxz	gaerr			; Error return
	or	dh,HE_DISCARDED 	; and mark as discarded
	mov	[bx].he_flags,dh	; Set handle flags
	jmp	short gax
gaerr1:
	dec	dx			; Free block if no available
	mov	es,dx			; handles.
	call	gmarkfree
gaerr:
	xor	dx,dx			; DX = 0 means NOT out of memory
	xor	ax,ax			; Return AX = 0 to indicate error
	jmp	short gax
ga1:
	call	gsearch 		; Search for block big enough
	jz	gax			; Done, if couldn't get enough
	test	dl,GA_MOVEABLE		; Is this a moveable object?
	jz	gax			; No, all done
	call	halloc			; Yes, allocate handle for object in AX
	jcxz	gaerr1			; No handles, free memory
	mov	si,[bx].he_address	; Store back link to handle in header
	dec	si
	mov	es,si
	mov	ES:[di].ga_handle,bx	; Mark as moveable block
	mov	[bx].he_flags,dh	; Save discard level in handle
gax:
	mov	cx,ax
	ret


; GREALLOC - procedure to reallocate global memory object
;
;   Inputs:	AX = allocation flags
;		BX = #paragraphs for new size
;		CX = new owner field value
;		DX = existing handle
;		DS:DI = address of global heap info
;
;   Outputs:	AX = handle to object or zero
;		DX = size of largest free block if AX = 0
;		CX = AX
;

grealloc:
	push	bp
	mov	bp,sp
	push	ax
rflags	EQU	word ptr [bp-2]
	push	dx
h	EQU	word ptr [bp-4]
	push	cx
owner	EQU	word ptr [bp-6]
	push	bx
rsize	EQU	word ptr [bp-8]
	call	gdref
	mov	bx,rsize
	jz	racreate	    ; Do nothing with zero, free or discarded  handles
	or	bx,bx		    ; Are we reallocing to zero length?
	jnz	raokay1  	    ; No, continue
	jcxz	radiscard	    ; No, is handle locked?
rafail:
	xor	ax,ax		    ; Yes, return failure
	xor	dx,dx
	jmp	raexit

radiscard:			    ; No, then try to discard the object
	; Here to discard object, when reallocating to zero size.  This
	; feature is only enabled if the caller passes the moveable flag
	test	byte ptr rflags,GA_MOVEABLE ; Did they want to discard?
	jz	rafail		    ; No, then return failure.
	mov	al,GN_DISCARD	    ; AL = discard message code
	xor	cx,cx		    ; CX = discard level of 0 (means realloc)
	mov	bx,h		    ; BX = handle
	push	es
	mov	dx,es:[di].ga_owner	;* set owner for notify
	call	gnotify			;* notify that we are discarding
					;* note : no return value
	pop	es
	push	ES:[di].ga_owner    ; Save owner field
	push	ax
	call	gmarkfree	    ; Free client data
	pop	cx
	jz	rafixed 	    ; Return NULL if freed a fixed block
	mov	[si].he_address,cx  ; No, remember owner in handle table entry
	or	[si].he_flags,HE_DISCARDED  ; ...and mark discarded
	jmp	short rasame1	    ; Return original handle, except
				    ; GlobalLock will now return null.
rafixed:
	pop	ax
	xor	ax,ax
	jmp	raexit

rasame1:
        jmp     short rasame
raokay1:
        jmp     short raokay
rafail0:
	jmp	rafail

racreate:
	test	cl,HE_DISCARDED     ; Is this a discarded handle?
	jz	rafail0 	    ; No, return error
	or	bx,bx		    ; Are we reallocing to zero length?
	jz	rasame		    ; Yes, return handle as is.
	mov	ax,GA_MOVEABLE	    ; Reallocating a moveable object
	or	ax,rflags	    ; ...plus any flags from the caller
	mov	cl,[si].he_flags    ; ...plus saved segment type bits
	and	cl,GA_SEGTYPE
	or	al,cl
	or	ah,cl
	test	al,GA_DISCCODE	    ; Discardable code segment?
	jz	ranotcode
	or	al,GA_ALLOCHIGH     ; Yes, allocate high
ranotcode:
	mov	[di].gi_cmpflags,al ; Save flags for gcompact
	mov	cx,[si].he_owner    ; Use previous owner
	push	si		    ; save handle
	call	gsearch 	    ; Find block big enough
	pop	si		    ; restore existing handle
	jz	racreate1
	xor	[si].he_flags,HE_DISCARDED  ; and mark as not discarded
	mov	[si].he_address,ax  ; Set new client data address
	mov	ch,[si].he_flags    ; Get handle flags

⌨️ 快捷键说明

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