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

📄 nhlhcore.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	TITLE	NHLHCORE - Core Local Heap utilities
;***
;NHLHCORE - Core Local Heap utilities
;
; Copyright <C> 1987, Microsoft Corporation
;
;Purpose:
; This module contains the core local heap utilities that are required to
; support /O programs which use string space and simple OPEN statements. Field
; manipulations and additional CHAIN support is elsewhere.
;
;******************************************************************************
;
; Near Heap Support
;
; The near heap support code deals with three pieces:
;
;	Local Heap	- Contains FDBs & Dynamic (small) arrays & QBI tables
;	String Space	- Strings and FIELDed string entries
;	Variable Heap	- Interpeter Only, value tables
;
; In memory, the heaps, associated variables and stack are layed out as
; follows:
;
;			   High Memory (DGROUP)
;
;			+--+--+--+--+--+--+--+--+
; b$HEAP_FIRST	-->	|			| odd:	last useable physical
;			+--+--+--+--+--+--+--+--+	byte of Heap
; b$NH_last	-->	|			| even: last useable physical
;			\ 			\ 	word of Heap
;				Local Heap
;			\ 			\
;			|			|
;			+--+--+--+--+--+--+--+--+
; b$HEAP_END	-->	|    LH_END Constant	| odd: ?
;			+--+--+--+--+--+--+--+--+
;			|			|
;			+			+
; b$STRING_END	-->	|			| even: word containing 0xFFFF
;			\ 			\
;				String Space
; b$NH_First	-\ 	\ 			\
; b$STRING_FIRST --\-->	|			| first useable byte/word
;			+--+--+--+--+--+--+--+--+ \
; b$HEAP_FIRST_SWAP --> |			|  \
;			\ 			\   \
;			      Variable Heap	     Interpeter Only
;			\ 			\   /
; b$HEAP_END_SWAP   --> |			|  /
;			+--+--+--+--+--+--+--+--+ /
;			|			|
;			+			+
; __atopsp	-->	|			| last useable word of stack
;			\ 			\
;				  Stack
;			\ 			\
; b$pend	-->	|			| first useable word of stack
;			+--+--+--+--+--+--+--+--+
;
;==============================================================================
;
;
; Heap Entry:
;
;			+--+--+--+--+--+--+--+--+	High memory
; Pointer to entry -->	|    Entry Type Byte	|
;			+--+--+--+--+--+--+--+--+
;			| File #, if applicable |
;			+--+--+--+--+--+--+--+--+
;			|			|
;			+   Total Entry Size	+
;			|			|
;			+--+--+--+--+--+--+--+--+
;			|     Back Pointer	|
;			+ (Pointer to		+
;			|	 owner pointer) |
;			+--+--+--+--+--+--+--+--+
;			| (offset part of sd	|
;			+  for fielded string	+
;			|  if applicable)	|
;			+--+--+--+--+--+--+--+--+
;			| (length part of sd	|
;			+  for fielded string	+
;			|  if applicable)	|
;			+--+--+--+--+--+--+--+--+
;			|			|
;			\ 			\
;				 Data
;			\ 			\
; Start of Data -->	|			|
;			+--+--+--+--+--+--+--+--+
;			|			|
;			+   Total Entry Size	+
;			|  (Same as in header)	|
;			+--+--+--+--+--+--+--+--+	Low memory
;
; The pointer to an entry normally points to the type byte in the header; since
; length of the entry (hdr + data + trailer length word) is kept at the start
; and the end of the block, it is easy to access; subtract that length from the
; current entry pointer, and it will be pointing to the same place in the next
; hdr - - - yes, since the heap grows down, subtracting from the pointer moves
; you "forward" in the heap. Heap entries can be of any even-byte size; headers
; are 6 bytes in length, except for fdb's, which have 10-byte headers.
;
;==============================================================================
;
; Internal structure of (simple) fielded strings.
;
; FDB:
;
;    /--+-----------------------+--/ /--+---------------+--/ /--+-------+
;	|   Field Buffer	|	|  String Desc	|	|LH_FILE|
;    /--+-----------------------+--/ /--+------------+--+--/ /--+-------+
;	       ^   ^	   ^		      ^      |
;	       |   |	   |		      |      |
; Individual   |   |	   +-----------+      |      |
; Static       |   |		       |      |      |
; String       |   +-------+	       |      |      |
; Descriptors: |	   |	       |      |      |
;	       |	   |	       |      |      |
;	  +-------+   +-------+   +-------+   |      |
;	  |  SD   |   |   SD  |   |  SD   |   |      |
;	  +-------+   +-------+   +-------+   |      |
;		^	    ^		^     |      |
; Fielded	|	    |		|     |      |
; String	+----+	    ++	     +--+     |      |
; BackPointer	     |	     |	     |	      |      |
; String:	     |	     |	     |	      |      |
;		     |	     |	     |	      |      |
;	    +---------------------------------+      |
;	    |	     |	     |	     |		     |
;	    |	  +----------------------------------+
;	    |	 \/  |	     |	     |
;	+---+---+----+--+----+--+----+--+--/
;	| BkPtr | SD Ptr| SD Ptr| SD Ptr|
;	+-------+-------+-------+-------+--/
;
; In summary, the FDB contains a string descriptor which references a string
; (the fielded string backpointer string) containing pointers to several string
; descriptors. These string descriptors (static, in this example) reference
; locations in the FIELD buffer in the FDB, and define the position and length
; of the individual FIELDs.
;
; The backpointer string can grow as additional FIELD statements are executed,
; and can shrink at CHAIN time. Since it is a string, it is also subject to
; movement as string-space compaction occurs. The compaction code must be
; sensitive to the pointers involved in such movement.
;
; When the fielded strings are defined in  a static string array, operation is
; essentially the same as individual static strings. The static SD's do not
; move, and dereferencing performed by any calling code looks exactly like
; static individual SD's.
;
;
; Internal structure of fielded strings in dynamic arrays.
;
; FDB:
;
;    /--+-----------------------+--/ /--+---------------+--/ /--+-------+
;	|   Field Buffer	|	|  String Desc	|	|LH_FILE|
;    /--+-----------------------+--/ /--+------------+--+--/ /--+-------+
;	       ^   ^	   ^		      ^      |
;	       |   |	   |		      |      +------------------+
; Array of     |   |	   +---+	      | 			|
; String       |   |	       |	      +---------------------+	|
; Descriptors: |   +---+       |				    |	|
;	       |       |       |				    |	|
;	+------++------++------++--/ /--+-------+--/ /--+-------+   |	|
;	|  SD	|   SD	|  SD	|	| BkPtr |	|LH_ARRA|   |	|
;	+-------+-------+-------+--/ /--+-----+-+--/ /--+-------+   |	|
;	       ^       ^       ^	      | 		    |	|
; Fielded      |       |       |	      | 		    |	|
; String       +-----+ +-----+ +-----+	      +----+		    |	|
; BackPointer  ^     |	     |	     |		   |		    |	|
; String:      +-----|-------|-------|----------+  |		    |	|
;		     |	     |	     |		|  |		    |	|
;	    +-------------------------------------------------------+	|
;	    |	     |	     |	     |		|  |			|
;	    |	  +-----------------------------------------------------+
;	    |	 \/  |	     |	     |		|  |
;	+---+---+----+--+----+--+----+--+--/	|  |
;	| BkPtr | SD Ptr| SD Ptr| SD Ptr|	|  |
;	+-------+-------+-------+-------+--/	|  |
;						|  |
; String	 +------------------------------+  |
; Array 	 |				   |
; Descriptor:	 |     +---------------------------+
;		 |    \/
;		++------+--/
;		|DatPtr |
;		+-------+--/
;
;
; The added complication of dynamic fielded string arrays is that the string
; descriptors live in the local heap, and hence can move, in addition to the
; backpoint string, which lives in string space and can also move. Both LH and
; SS code must update pointers appropriately.
;
;==============================================================================
	INCLUDE switch.inc
	INCLUDE baslibma.inc
	INCLUDE files.inc
	INCLUDE rmacros.inc

	USESEG	_DATA
	USESEG	_BSS
	USESEG	NH_TEXT

	INCLUDE seg.inc
	INCLUDE nhutil.inc	;for heap definitions
	INCLUDE idmac.inc
	INCLUDE array.inc	;for array definitions


sBegin	_BSS

	externW b$STRING_END		;defined in NHSTUTIL.ASM
	externW b$STRING_FREE		; defined in NHSTUTIL.ASM
	externW b$NH_first		;defined in NHINIT.ASM
	externW b$PTRFIL		;defined in GLOBAL.INC

;NOTE: Variable Heap support code requires next 4 data items be contiguous [23]

	globalW b$HEAP_FIRST,,1 	;heap start pointer
	globalW b$HEAP_FREE,,1
	globalW b$HEAP_END,,1
	globalW b$P_HEAP_GROW,,1	

;NOTE: Variable Heap support code requires next 4 data items be contiguous [23]

	globalW b$HEAP_FIRST_SWAP,,1	 
	globalW b$HEAP_FREE_SWAP,,1	 
	globalW b$HEAP_END_SWAP,,1	 
	staticW P_HEAP_GROW_SWAP,,1	 

	globalW b$fVarHeapActive,,1	 ; non-0 when variable heap
					 ; is active

sEnd	_BSS

sBegin	_DATA

	globalW b$pFHRaiseBottom,Near_Ret,1  ;vector for B$FHRaiseBottom

	globalB b$Clearing,0,1		; CLEAR statement in process flag
sEnd	_DATA

	externFP B$ULDataRelease ;releases ul Data images
	externFP CompressHelp	

sBegin	NH_TEXT

	ASSUMES CS,NH_TEXT

	PUBLIC	B$LHNXTFIL	; find next file entry in heap

	PUBLIC	B$LHADJ	;adjust heap entry
	PUBLIC	B$LHDALC	;deallocate heap entry

	PUBLIC	B$LHFLDDESCADJ	; delete/adjust descriptor in backpointer string
	PUBLIC	B$LHDALCALLFLD	; deallocate all fielded strings from heap entry

	PUBLIC	B$LHSetFree	;set free heap entry pointer
	PUBLIC	B$LH_ALC_FREE	;[ln]
	PUBLIC	B$LH_PTR_FROM_DATA 
	PUBLIC	B$LH_CPCT	
	PUBLIC	B$LH_FROM_SS	;[ln]
	PUBLIC	B$LH_PTR_CHECK	;[ln] check entry at [SI] for consistency
	PUBLIC	B$LH_SCAN	;[ln]

	PUBLIC	B$NHINIT	;initialize dynamic space


	externNP B$LH_I_ADJ	;[ln] adjust backptrs to any owners in this entry
	externNP B$VAR_ALC_GROW ;[ln]

	externNP B$ERR_SSC		 
	externNP B$STCPCT
	externNP B$STADJ
	externNP B$STINIT
	externNP B$STSetFree
	externNP B$SSClean	; clean string space

ASSERT_NOT_VARHEAP	MACRO	SEG	;
	ENDM				;


	PAGE
;***
; LH_ALC_GROW - Grow local heap to support allocation of a block of given size
; Purpose:
;	Added with revision [23].
;
; Inputs:
;	ES = DS
;	BX = total size of local heap space to be allocated
;	DL = type of heap entry to allocate.
;	CL = if DL=LH_FILE, file number
;	CX = if DL anything else, ptr to owner (where backptr should point to)
; Outputs:
;	Carry Clear if allocation accomplished successfully
; Modifies:
;	SI
; Exceptions:
;
;****
DbPub	LH_ALC_GROW
LH_ALC_GROW:
;	Step 3 - Get free string entry to heap space, test free entry.

	CALL	B$LH_FROM_SS	;[ln] get free string from string space
	CALL	B$LH_ALC_FREE	;test free entry for room
	JNC	LH_ALC_GROW_DONE; allocated - jump to return to string

;	Step 4 - Perform string compaction, get free string, test free entry.

	CALL	B$STCPCT	;perform the string compaction
	CALL	B$LH_FROM_SS	;[ln] get free string from string space
	CALL	B$LH_ALC_FREE	;test free entry for room
	JNC	LH_ALC_GROW_DONE; allocated - jump to return to string
;
;	Step 5 - Kick FH out of DS if possible
;
	CALL	[b$pFHRaiseBottom] ;[46]
	CALL	B$LH_FROM_SS	;[ln] get free string from string space
	CALL	B$LH_ALC_FREE	; test free entry for room
	JNC	LH_ALC_GROW_DONE;allocated jump to return string

;
;	Step 6 - Kick UL data images out of FH and raise the bottom

	PUSH	AX		;preserve AX-DX across call to
	PUSH	BX		;B$ULDataRelease, as the far
	PUSH	CX		;call dispatcher to the quicklibrary
	PUSH	DX		;can honk on these registers.
	CALL	B$ULDataRelease ;free UL data images if allocated
	POP	DX		
	POP	CX		
	POP	BX		
	POP	AX		;recover regs

	CALL	[b$pFHRaiseBottom] ;give FH's free space to NH
	CALL	B$LH_FROM_SS	;[ln]get free string from string space
	CALL	B$LH_ALC_FREE	;test free entry for room
	JNC	LH_ALC_GROW_DONE;allocated jump to return string

;
;	Step 7 - Kick Help out of FH and raise the bottom

	PUSH	AX		;preserve AX-DX across call to
	PUSH	BX		;CompressHelp
	PUSH	CX		
	PUSH	DX		
	CALL	CompressHelp	;Free the help system
	POP	DX		
	POP	CX		
	POP	BX		
	POP	AX		;recover regs

	CALL	[b$pFHRaiseBottom] ;give FH's free space to NH
	CALL	B$LH_FROM_SS	;get free string from string space
	CALL	B$LH_ALC_FREE	;test free entry for room

Near_Ret:			;Near Return for vector
LH_ALC_GROW_DONE:
	RET

;***
; B$LH_FROM_SS - get local heap space from string space
; Purpose:
;	Determine if a free entry exists at the end of
;	string space.  If so, change the string and heap
;	space pointers so that it is now part of the local
;	heap space.
;
;	Mostly rewritten with revision [53].
;
; Strategy (order of attempts swapped with revision [64]):
; (1)	If the last entry in the LH is a free entry, tack the free
;	string bytes onto that entry and move b$HEAP_END past it.
;
; (2)	If the last entry in the LH is NOT a free entry and the free
;	string is large enough to create a heap entry (LH_STD_HDR_LEN
;	bytes + 2 bytes for back length), then create a new LH entry
;	with the free space.
;
;	If neither (1) or (2) is possible, then we can't give any of
;	the free string to the LH, just exit.
;
; Inputs:
;	None.
; Outputs:
;	[b$HEAP_FREE] = pointer to new (or enlarged) free heap entry.
; Modifies:
;	None.
; Exceptions:
;	None.
;****
B$LH_FROM_SS:
	ASSERT_NOT_VARHEAP NH_TEXT	
	PUSH	AX			;save registers...
	PUSH	SI
	PUSH	DI
	CALL	B$STSetFree		;SI points to trailing free string
	MOV	AX,[b$STRING_END]	;get end pointer in AX
	SUB	AX,SI			;compute size of free string
	JZ	LH_SS_RETURN		;if no free bytes, exit quickly

;	Size of free string (including header) is in AX.
;	Pointer to free string header is in SI.

DbAssertTst AX,Z,1,NH_TEXT,<Free string size odd in B$LH_FROM_SS>

;	(1) If the last entry in the LH is free, tack the new empty space
;	    on to it.

	MOV	DI,[b$HEAP_END] 	;[DI] = heap END entry
	CMP	DI,[B$HEAP_FIRST]	; is END the only entry?
	JE	LH_SS_TRY_2		; yes, go create a free entry
	ADD	DI,[DI+1]		;[DI] = last entry before END
	CMP	[DI].LHTYPE,LOW LH_FREE ;is entry unallocated?
	JNE	LH_SS_TRY_2		;no, go try next option
	ADD	AX,[DI].LHLEN		;compute new length
	JMP	SHORT LH_SS_FINISH_UP	; finish updating pointers and exit

;	(2) If there are enough free bytes to create a new free entry at the
;	    end of the LH, do that.

LH_SS_TRY_2:
	CMP	AX,LH_STD_HDR_LEN+2	;enough free space?
	JB	LH_SS_RETURN		;if not, we can't do anything

⌨️ 快捷键说明

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