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

📄 nhstutil.asm

📁 Microsoft MS-DOS6.0 完整源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;	stack and will be lost at exit.  The string will be transferred
;	to a temp just before the sd is trashed.  It is guaranteed that
;	b$curlevel will be adjusted appropriately before this routine
;	is called. If the SD is 0 length, a ptr to b$nuldes will be returned.
;Entry:
;	psdOwner - pointer to sd currently owning string.
;Exit:
;	AX - pointer to temp sd that is new owner of string
;	     (b$nuldes if 0 length).
;Uses:
;	Per convention.
;Exceptions:
;	B$ERR_ST if no temps are left.
;****

cProc	B$STMakeTemp,<PUBLIC,FAR>
parmW	psdOwner
cBegin
	XOR	AX,AX		
	CMP	WORD PTR[TMPHDR],AX ;are there any temps left
	JZ	TEMPOV		;brif not - error out

	MOV	BX,[psdOwner]
	CMP	[BX],AX 	;is this a null (0-length) string?
	JNZ	NotNullstr	;brif not

	MOV	AX,OFFSET DGROUP:b$nuldes ;get ptr to b$NulDes
	JMP	SHORT BSTMakeTempX ;return it in ax

NotNullStr:			
	cCall	MakeTemp	;call near routine to do the work
	XCHG	AX,BX		;return new sd in AX
BSTMakeTempX:			
cEnd

cProc	MakeTemp,<NEAR>
cBegin	<nogen>
	PUSH	SI		;preserve SI
	PUSH	[BX]		;push size of string
	MOV	BX,[BX+2]	;[BX] = ptr to string data
	JMP	SHORT ALCTMP	;jump to common code to make the temp
				;the new owner
cEnd	<nogen>

PAGE
;***
; B$STCHKTMP - Check for temporary string descriptor
; Function:
;	Check to see if the string descriptor is a temporary.
; Inputs:
;	BX = Address of string descriptor
; Outputs:
;	Carry flag set if a temp
;	Carry clear in not
; Modifies:
;	None
; Exceptions:
;	None
;****

B$STCHKTMP:			;[C1]
	CMP	BX,OFFSET DGROUP:TMPH
	JNC	RETL		;If above high end, not a temp
	CMP	BX,OFFSET DGROUP:TMPL
	CMC
	RET
PAGE
;***
; B$STGETSTRLEN - get string length
; Purpose:
;	Computes the byte length of a zero-terminated ASCII string.
;
; Inputs:
;	BX = offset of string
; Outputs:
;	AX = Length of the line (not including 00)
; Modifies:
;	None.
; Exceptions:
;	None.
;****

B$STGETSTRLEN:
	PUSH	ES		
	PUSH	DS		
	POP	ES		;Set ES = DS
	PUSH	CX
	PUSH	DI
	MOV	CX,-1		;Scan up to 65535 characters
	MOV	AL,0		;Search for a zero
	MOV	DI,BX
	REPNE	SCASB		;Scan for a 00
	MOV	AX,CX		;Amount of the 65535 left
	NOT	AX
	DEC	AX
	POP	DI
	POP	CX
	POP	ES		
	RET
PAGE
;***
;B$STALCTMPCPY - Allocate a temp string copy.
;DBCS-callback
;
;Purpose:
;	Allocate a temporary string of the length specified.  Copy the
;	data from the string whose descriptor was passed to the new string.
;	Does not deallocate the original string.
;
;Inputs:
;	BX = Length of string to copy.
;	DX = Address of string data to copy
;
;Outputs:
;	BX = Address of temp string descriptor
;
;Uses:
;	Per Convention
;
;Preserves:
;	AX, CX
;
;Exceptions:
;	None
;****

B$STALCTMPCPY: 		;[C1]
	PUSH	ES		
	PUSH	DS		
	POP	ES		;Set ES = DS
	PUSH	CX
	MOV	CX,BX		;Get length in CX
	PUSH	SI
	MOV	SI,DX		;Point to source of string data
	CALL	B$STALCTMP	;[C1]Get a temporary string of the right length
	PUSH	DI
	MOV	DI,DX		;String data destination
	MOV	DX,SI		;Restore DX
	INC	CX		;Round up if odd
	SHR	CX,1		;Move by words
	REP	MOVSW
	POP	DI
	POP	SI
	POP	CX
	POP	ES		
	RET
PAGE
;***
; B$STDALCALLTMP - Deallocate all temporary strings
; Purpose:
;	Free all temporary strings and descriptors which were
;	allocated at or above the specified level.
;
; Inputs:
;	AX = program level at or above which temporary strings
;	     will be deallocated.  Use 0 (the minimum level) to
;	     deallocate ALL temporary strings.
; Outputs:
;	None.
; Modifies:
;	None.
; Exceptions:
;	None.
;****

B$STDALCALLTMP:			;[C1]
	PUSH	BX
	MOV	BX,OFFSET DGROUP:TMPL ;First string descriptor
DTSLOOP:
	CMP	WORD PTR[BX+4],AX ;string allocation level >= specified
	JL	NEXTMP		;skip if not
	CALL	DELTMP		;otherwise delete it
NEXTMP:
	ADD	BX,LENTEMP	;Next temp descriptor
	CMP	BX,OFFSET DGROUP:TMPH ;Done yet?
	JB	DTSLOOP
	POP	BX
RETL:
	RET
PAGE
;***
;B$STDALCTMP - Deallocate if temporary string
;DBCS-callback
;
;Purpose:
;	Check to see if the descriptor is a temporary one.
;	If so, deallocate its string data and release the descriptor
;	for future use.
;
;Inputs:
;	BX = Address of string descriptor
;
;Outputs:
;	None.
;
;Uses:
;	Per Convention
;
;Preserves:
;	AX, BX, CX, DX
;
;Exceptions:
;	None.
;****

B$STDALCTMP:			;[C1]
	CALL	B$STCHKTMP	;[C1]See if temp string
	JNC	RETL		 ;If not, leave it
DELTMP:
	CALL	B$STDALC	;[C1]Free the space

;***
; B$STDALCTMPDSC - deallocate temporary descriptor
; Purpose:
;	Deallocate the temporary string descriptor pointed by BX and
;	relink it in the temporary descriptor chain for subsequent
;	allocation.
;
; Inputs:
;	BX = address of temporary string descriptor
; Outputs:
;	None.
; Modifies:
;	None.
; Exceptions:
;	None.
;****

B$STDALCTMPDSC:

;	Make sure that we do not attempt to deallocate a temp twice

DbAssertRel	[BX+4],NZ,-1,NH_TEXT,<Attempted to dealloc an already dealloced string temp>

	PUSH	AX
	MOV	AX,BX
	XCHG	AX,[TMPHDR]	;Make this one the first free
	MOV	[BX],AX 	;Set link to former first one
;	MOV	WORD PTR[BX+2],-1 ;Make it easy to see its free
	MOV	WORD PTR[BX+4],-1 ; < min level (0) means free temp desc
	POP	AX
	RET
PAGE
;***
;B$STALCTMPSUB - Allocate temporary substring copy
;DBCS-callback
;
;Purpose:
;	Create a temporary string and copy the specified portion of the given
;	string into it. The given string is deleted if it is a temp.
;
;	The starting position in the string is specified as an offset from
;	the beginning of the string.  Thus 0 <= CX <= Len(BX)-DX
;
;Inputs:
;	BX = Address of string descriptor
;	CX = Starting position within string
;	DX = Length
;
;Outputs:
;	BX = Address of temp string descriptor
;
;Uses:
;	Per Convention
;
;Preserves:
;	AX, CX, DX
;
;Exceptions:
;	None.
;****

B$STALCTMPSUB: 			;[C1]
	PUSH	ES		
	PUSH	DS		
	POP	ES		;Set ES = DS
	PUSH	AX		;Save registers
	PUSH	CX
	PUSH	SI
	PUSH	DI

	MOV	SI,CX		;SI = offset into string
	MOV	AX,BX		;AX = source string descriptor
	MOV	CX,DX		;CX = length
	MOV	BX,DX		;BX = length
	CALL	B$STALCTMP	;[C1]Allocate temp string
	MOV	DI,DX		;DI = temp string contents address
	XCHG	AX,BX		;AX = temp string descriptor
				;BX = source string descriptor
	ADD	SI,[BX+2]	;add in old string contents address
	CALL	B$STDALCTMP	;[C1]delete old temp string
	XCHG	AX,BX		;BX = new string descriptor
	MOV	DX,CX		;get length back in DX to leave it unchanged
	INC	CX		;if odd, round up to even
	SHR	CX,1		;bytes to words
	REP	MOVSW		;move into temp string

	POP	DI
	POP	SI
	POP	CX
	POP	AX
	POP	ES		
	RET
PAGE
;***
; B$STDALC - Deallocate string
; Purpose:
;	Deallocate the string data pointed by the string descriptor.
;
; Inputs:
;	BX = Address of string descriptor.
; Outputs:
;	None.
; Modifies:
;	None.
; Exceptions:
;	None.
;****

B$STDALC:			;[C1]
	PUSH	ES		
	PUSH	DS		
	POP	ES		;Set ES = DS
	PUSH	AX		;save register
	XOR	AX,AX		;clear to set flag for deletion
	CALL	B$STADJ	;call routine for string data deallocation
	POP	AX		;restore register
	POP	ES		
	RET			;return to caller
PAGE
;***
; B$STADJ - deallocate/adjust string data
; Function:
;	Deallocates or adjusts the string data pointed by the
;	string descriptor in BX.  If AX=0, the data is deallocated.
;	If AX<>0, the string backpointer is adjusted by the value
;	of AX.
;
; Inputs:
;	AX = adjustment value
;	     AX=0  - deallocate string.
;	     AX<>0 - adjust string backpointer.
;	BX = Address of string descriptor.
;	DS = segment that heap is in
;	ES = segment that state vars are in
; Outputs:
;	None.
; Modifies:
;	None.
; Exceptions:
;	None.
;****
assumes	ES,DGROUP		
assumes	DS,NOTHING		
B$STADJ:
	CMP	WORD PTR [BX],0 ; is string allocated?
	JZ	ADJSTR_EXIT	; brif not

	PUSH	CX		;save register
	PUSH	SI
	MOV	SI,[BX+2]	;Get pointer to string data

;	Test if string is in string space - from [b$STRING_FIRST] to
;	[b$STRING_END].

	CMP	SI,ES:[b$STRING_FIRST] ;test if before string space
	JB	ADJSTR_RETURN	;if less, then constant, do not deallocate
	CMP	SI,ES:[b$STRING_END]	;test if after string space
	JA	ADJSTR_FIELDED	;if more, then fielded string, jump

;	String is in string space.  First adjust the backpointer by AX.
;	Then test if deallocation is requested and, if so, replace
;	backpointer with free string header with <data length>+1.

	ADD	[SI-2],AX	;adjust backpointer of string
	OR	AX,AX		;test if deallocation was requested
	JNZ	ADJSTR_RETURN	;if so, then finished, jump
	MOV	CX,[BX] 	;Get length of string to free
	INC	CX		;Round up if odd
	OR	CL,1		;And set free bit
	XCHG	CX,[SI-2]	;Get backpointer and set free length
	CMP	CX,BX		;Check backpointer
	JE	ADJSTR_RETURN	;if equal, then just return
	PUSH	ES		;force DS = ES incase of CHAIN
	POP	DS		;sets up DS = BASIC DS
	JMP	B$ERR_SSC	;jump to error routine

;	String is in the local heap, probably a fielded string.
;	Call routine to delete descriptor from the appropriate heap
;	entry backpointer string.

ADJSTR_FIELDED:
	CALL	B$LHFLDDESCADJ	;delete descriptor in BX for heap entry

ADJSTR_RETURN:
	POP	SI		;restore registers
	POP	CX
ADJSTR_EXIT:			
	RET			;return to caller
assumes	DS,DGROUP		
assumes	ES,NOTHING		
PAGE
;***
; B$STPUTZ - Put zero at end of string
;
; Inputs:
;	BX = Address of string descriptor
; Function:
;	Make into a string with a zero byte on the end. If length is presently
;	odd, just jam a zero into the extra byte. If even, create a temp
;	one byte longer and put the zero there.
; Outputs:
;	BX = Address of string descriptor
; Registers:
;	Only BX and F affected.
;****

B$STPUTZ:
	PUSH	DX
	MOV	DX,[BX]
	PUSH	CX
	XOR	CX,CX		;Offset = 0
	INC	DX		;Length = old length + 1
	CALL	B$STALCTMPSUB	;[C1]Always copy string into string space
	DEC	DX
	POP	CX

⌨️ 快捷键说明

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