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

📄 osstmt.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:

ExecNullCmd:			
	XOR	AX,AX		;tell B$SHELL to use current ENV block
	cCall	B$Shell	;call common code to do the SHELL.

	PUSH	AX		;Save return code for later

	cCall	B$ShellRecover ;reset runtime to PreSHELL state.

;	Now that runtime is restored, check return code

	POP	AX		;recover error code
	OR	AX,AX		;error
	JZ	SHL_NOT_FAILED	;if not, then jump
	CMP	AX,8		;test if out of memory
	JE	ShellMemErr	;if so, then jump
	JMP	B$ERR_FC	;else illegal function call
ShellMemErr:			
	JMP	B$ERR_OM	;give out-of-memory error
SHL_NOT_FAILED:


cEnd


;***
; B$SENV - Environ statement
; Purpose:
;	Argument is a string of the syntax <env_name>=<env_value>.
;	If <env_value> is nonnull and <env_name> exists, replace it.
;	If <env_value> is nonnull and <env_name> does not exist, add it.
;	If <env_value> is null, delete <env_name> if it exists.
;
; Inputs:
;	string descriptor of argument string
; Outputs:
;	None.
; Modifies:
;	None.
; Exceptions:
;	B$ERR_FC if function argument error.
;******************************************************************************

cProc	B$SENV,<PUBLIC,FAR>,<SI,DI,ES> 
parmSD	sdEnviron		
cBegin
	PUSH	DS		; Set es=DS
	POP	ES
	MOV	BX,sdEnviron	;get environment descriptor in BX
	mov	cx,[bx] 	;length of string
	mov	si,[bx+2]	;count in string
	push	bx
	mov	dx,cx
	push	dx
	push	si
	jcxz	errfc
envsf1: 			;look for blank or equals:  address of
	lodsb			;string to move into environment
	cmp	al,' '
	jz	envsf2
	cmp	al,'='
	jz	envsf2
	loop	envsf1
	JMP	SHORT ERRFC	;error if no delimiter

envsf2:
	sub	dx,cx		;size of parm
	jz	errfc		;zero is bad
envsf3:
	dec	cx		;adjust length
	jz	envsf4		;no text follows - delete
	lodsb
	CMP	AL,'='		;test for equals sign
	JNZ	ENVS3A		;if not, then jump
	DEC	CX		;adjust length
	JZ	ENVSF4		;no text follows - delete
	LODSB			;get character after '='
	JMP	SHORT ENVS3B	;jump to test for semicolon, etc.
ENVS3A:
	cmp	al,' '
	jz	envsf3		;strip leading blanks
ENVS3B:
	cmp	cx,1		;if 1 left
	jne	envsf4
	cmp	al,';'		; and it is semi-colon
	jz	envsf3		;then assume delete
envsf4:
	dec	si		;adjust to beginning of text
	pop	di		;start of string
	push	cx		;save length of arg text
	CALL	B$FIRST_ENV	;get start of env in bx
	mov	cx,dx		;cx = length of parm
envsf5:
	mov	dx,si		;dx = start of next
	mov	si,bx		;si = start of this
	push	di		;save string start
	jz	envsf9		;if end, add new parm and text
	push	cx		;save parm length
	cld
	repz	cmpsb		;compare parm with env parm
	je	envsf7		;matched
envsf6:
	mov	si,dx		;don't want tz unless real end
	CALL	B$NEXT_ENV	;go to next env parm
	pop	cx		;length and
	pop	di		; parm start back
	jmp	envsf5

errfc:	jmp	B$ERR_fc

envsf7:
	lodsb			;get next byte from environment
	cmp	al,'='		;must have equals to be a match
	jne	envsf6		;try next
	pop	ax		;trash parm length
	mov	si,dx		;si = address of next parm
	mov	di,bx		;di = address of this parm
	mov	cx,es:b$env_len ;get total length of environment
	sub	cx,dx		;cx=endnext (length to compress)
	inc	cx		;copy includes table terminator
	push	di
	push	es		;save seg of string
	push	ds		;move env. seg into es
	pop	es
	rep	movsb		;compress
	pop	es		;restore seg of string
	pop	si		;start of this parm or end
envsf9:
	CALL	B$NEXT_ENV	;find end of table
	jnz	envsf9
	mov	di,si		;di = end of env table
	push	ds
	push	es
	pop	ds
	pop	es		;ds = string seg, es = env seg
	pop	si		;string start
	pop	ax		;ax = length of arg text
	pop	cx		;string length

	or	ax,ax
	jz	envsfx		;if arg text length then done
	mov	ax,di		;ax = current length of environ
	add	ax,cx		;+ new size
;INC	AX		;include terminator byte in length
assumes	ES,NOTHING		
	cmp	ax,b$env_len	;check if overflow
	jb	envs10		; no overflow
	push	ds
	pop	es
	jmp	B$ERR_om	;give out of memory error
envs10:
	lodsb
	cmp	al,'='		;blanks to right of '=' are included
	jz	envs11
	cmp	al,' '		;skip blanks
	jz	envs11
	stosb
	loop	envs10
	jmp	SHORT envsft	;terminate
envs11:
	DEC	CX		;one less character
	CMP	AL,' '		;test for blank character
	JNE	ENVS12		;if not blank, then jump
	JCXZ	ENVSFT		;if end of string, jump
	LODSB			;get the next character
	JMP	SHORT ENVS11	;process the character
ENVS12: 			;character after leading blanks
	CMP	AL,'='		;test for equals sign
	JE	ENVS13		;process rest of string as is
	PUSH	AX		;save character after blanks
	MOV	AL,'='		;put in equals sign
	STOSB			;and place it in the table
	POP	AX		;restore old character
ENVS13: 			;start of text string
	STOSB			;store first char (or explicit =)
	rep	movsb
envsft: 			;terminate label
	xor	ax,ax
	stosw			;00 ends env table
envsfx: 			;exit label
	push	ds
	pop	es
	pop	bx
	CALL	B$STDALCTMP	; delete if temp string desciptor
cEnd

;***
; B$SICT - IOCTL statement
; Purpose:
;	Send the specified string argument as an I/O-control
;	function to the file.
;
; Inputs:
;	file number
;	string to send
; Outputs:
;	None.
; Modifies:
;	None.
; Exceptions:
;	B$ERR_IFN if illegal file number.
;	B$ERR_FC if function error.
;	B$ERR_IOC if IOCTL error.
;******************************************************************************


cProc	B$SICT,<PUBLIC,FAR>,<SI> 
parmW	fileNum
parmSD	sdCtl			
cBegin
	MOV	BX,fileNum	;put file number in BX
	CALL	B$LHFDBLOC	; find FDB
	JZ	BADIFN2
	MOV	BX,sdCtl	; [BX] = string desc
	MOV	DX,[BX+2]	
	MOV	CX,[BX] 	
	PUSH	BX		; save
	MOV	AL,3
	FDB_PTR ES,SI,SI	;get FDB pointer
	MOV	BX,FileDB.FD_HANDLE 
	OR	BX,BX		;if zero, one of basic's devices
	JZ	ERRCTL2		
	CALLOS	IOCTL,ERRCTL,BX,CX,DX
	POP	BX		
	cCall	B$STDALCTMP	; deallocate it if it was temp
cEnd

ERRCTL2:			
	JMP	SHORT ERRCTL	
BADIFN2:			
	JMP	SHORT BADIFN	



;***
; B$FEVS - ENVIRON$ function with string argument
; Purpose:
;	With <env_name> as an input argument, return <env_value> if
;	the entry "<env_name>=<env_value>" is in the environment table.
;
; Inputs:
;	string descriptor of <env_name>
; Outputs:
;	AX = ptr to string descriptor of <env_value>
; Modifies:
;	None.
; Exceptions:
;	B$ERR_FC if function error.
;******************************************************************************

cProc	B$FEVS,<PUBLIC,FAR>,<SI,DI,DS,ES>	
parmSD	sdEnv			
cBegin
	PUSH	DS		
	POP	ES		
assumes	ES,DGROUP		
	MOV	BX,sdEnv	;get string desc. in BX
	MOV	SI,[BX+2]	;address of string
	MOV	CX,[BX] 	;length
	MOV	DX,CX		;save
	PUSH	SI
	JCXZ	BADFC
ENVRS1:
	LODSB
	CMP	AL,' '		;error if embedded blanks
	JZ	BADFC
	CMP	AL,'='		;or '='
	JZ	BADFC
	LOOP	ENVRS1
	POP	DI		;address of string
	PUSH	DX		;save length
	CALL	B$FIRST_ENV	;get first env parm
	MOV	AX,CX		;save length of env table entry
	POP	CX		;length back
ENVRS5:
	MOV	DX,SI		;start of next
	MOV	SI,BX		;start of this
	JNZ	ENVR5A		;not end of list (yet)
	XOR	CX,CX		;end of list returns null string
	JMP	SHORT GOGOTENV	;and jump to process it
ENVR5A:
	PUSH	DI		;save
	PUSH	CX
	REPZ	CMPSB		;compare parms
	JZ	ENVRS7		;matched
ENVRS6:
	MOV	SI,DX
	CALL	B$NEXT_ENV	;get next
	MOV	AX,CX		;save length of env table entry
	POP	CX
	POP	DI
	JMP	ENVRS5
ENVRS7:
	CMP	BYTE PTR [SI],'=' ;must have equals
	JNE	ENVRS6
	INC	SI		;SI points after '=' now
	POP	CX		;restore string length
	POP	DI
	XCHG	CX,AX		;CX now length of table entry...
				;AX now length of string parameter
	SUB	CX,AX		;CX now length of '=' and value
	DEC	CX		;CX now length of just value
GOGOTENV:			
	CALL	GOTENV		; do the common code (returns DX:AX = sd)
	PUSH	AX		; save psd returned by GOTENV
	MOV	BX,sdEnv	
	PUSH	ES		
	POP	DS		; [DS] = dgroup again
assumes	ES,NOTHING		
	cCall	B$STDALCTMP	; deallocate it if it was temp
	POP	AX		; ax = pointer to descriptor
cEnd

ERRCTL:
	CMP	AX,ERRIDT
	JNE	BADFC		
	JMP	B$ERR_IOE

BADIFN:				
	JMP	B$ERR_IFN	
BADFC:
	JMP	B$ERR_FC


;***
; B$FEVI - ENVIRON$ function with integer argument
; Purpose:
;	Returns the ordinal i environment table entry, where
;	i is the input integer argument.
;
; Inputs:
;	integer value in range 1 to 255.
; Outputs:
;	AX = ptr to string descriptor to a copy of the table entry.
; Modifies:
;	None.
; Exceptions:
;	B$ERR_FC if function error.
;******************************************************************************

cProc	B$FEVI,<PUBLIC,FAR>,<SI,DI,DS,ES> 
parmW	EnvInt
cBegin
	PUSH	DS		
	POP	ES		;set es=ds
	MOV	BX,EnvInt	;get integer in BX
	MOV	DX,BX
	OR	BX,BX		;test for zero argument
	JZ	BADFC		;and error if so...
	CMP	BX,255
	JA	BADFC
	CALL	B$FIRST_ENV	;get first parm in env
ENVNF1:
	JZ	ENVNF2		;end, return null
	DEC	DX
	JZ	ENVNF2		;return pointer in BX
	CALL	B$NEXT_ENV
	JMP	SHORT ENVNF1
ENVNF2:
	MOV	SI,BX		;GOTENV needs pointer in SI
	CALL	GOTENV		;call common code (returns DX:AX = sd)
cEnd				

GOTENV:
	PUSH	DS		;save ENV segment
	PUSH	ES		;put DGROUP seg on stack
	POP	DS		;restore DS to DGROUP
	PUSH	CX		;save length
	MOV	BX,CX
	CALL	B$STALCTMP	; allocate string temp
	POP	CX		;count
	POP	DS		;get ENV segment back in DS
	XCHG	AX,BX		; [AX] = psd
	MOV	DI,DX		;target
	REP	MOVSB		;move into target
	RET			; return with [DX:AX] = sd or [AX] = psd

;***
; B$FICT - IOCTL$ function
; Purpose:
;	Returns a status string from the specified file using
;	an IOCTL call.
;
; Inputs:
;	 file number to get status
; Outputs:
;	AX = pointer to string descriptor of status string
; Modifies:
;	None.
; Exceptions:
;	B$ERR_FC if function call error.
;	B$ERR_IOC if IOCTL error.
;******************************************************************************

cProc	B$FICT,<PUBLIC,FAR>,<SI,DI,ES> 
parmW	fileNum
cBegin
	MOV	BX,fileNum	;get file number in BX
	CALL	B$LHFDBLOC	
	JZ	BADIFN		
	FDB_PTR ES,SI,SI	;get FDB pointer
	MOV	BX,FileDB.FD_HANDLE 
	OR	BX,BX		;if zero, one of basic's devices
	JZ	ERRCTL
	MOV	DX,OFFSET DGROUP:b$PATHNAM ; DX = buffer address
	MOV	AL,2		;read IOCTL info
	CALLOS	IOCTL,ERRCTL,BX,255,DX
	MOV	CX,AX		;[CX] = number of bytes read
	XCHG	AX,BX
	MOV	SI,DX		;address of ioctl data
	CALL	B$STALCTMP	; allocate string temp
	MOV	DI,DX		;target work area
	PUSH	DS		
	POP	ES		
	REP	MOVSB
	XCHG	AX,BX		;return sd in AX
cEnd


;***
; B$ERDV - return device error word
; Purpose:
;	Return the value of the device error word set by the
;	last error.
;
; Inputs:
;	None.
; Outputs:
;	AX = device error word.
; Modifies:
;	None.
; Exceptions:
;	None.
;******************************************************************************

cProc	B$ERDV,<PUBLIC,FAR>
cBegin
	MOV	AX,b$ERDEV
cEnd

;***
; B$ERDS - get device error string
; Purpose:
;	Returns the descriptor of the device error string.
;
; Inputs:
;	None.
; Outputs:
;	AX = address of device error string if set, otherwise null string.
; Modifies:
;	None.
; Exceptions:
;	None.
;******************************************************************************

cProc	B$ERDS,<PUBLIC,FAR>
cBegin
	MOV	BX,OFFSET DGROUP:b$ERDEVP ;address of string
	CMP	WORD PTR [BX],0 ;set yet ?
	MOV	AX,BX		;put sd in AX
	JNE	DVRET
	MOV	AX,OFFSET DGROUP:b$nuldes ;no - use null
DVRET:
cEnd

sEnd	OS_TEXT 		
	END

⌨️ 快捷键说明

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