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

📄 setargv.asm

📁 著名的C语言编辑器
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;	CX	=	number of expanded arguments (0 = no match)
;
WildExpand	proc	near

		push	ds
		mov	wild_argument, si
		mov	wild_argument+2, ds
		mov	wild_destin, di
		mov	wild_destin+2, es
		mov	word ptr wild_argc, 0
;
; Find the length of the path prefix, if any.
;
		mov	bx, si
WildFindPath:	lodsb
		and	al, al
		jz	WildEndPath
		cmp	al, '\'
		je	WildDelimiter
		cmp	al, ':'
		je	WildDelimiter
		cmp	al, '\'
		jne	WildFindPath
WildDelimiter:	mov	bx, si			; save addr past last delimiter
		jmp	SHORT WildFindPath
WildEndPath:	sub	bx, wild_argument
		mov	wild_path_len, bx

		mov	ah, 4eh
		mov	cx, wild_attr		; file attribute
		lds	dx, dword ptr wild_argument
		int	21h			; find first matching file ...
		jc	WildDone
;
; We have a matching file. Add it to the destination string (unless "." or "..")
;
WildAddArg:
;
; If directories are included (10h set in wild_attr), ignore "." and ".."
;
if	wild_attr AND 10h
		push	ss
		pop	ds
		lea	si,wild_ffblk.ff_name
		cmp	byte ptr [si],'.'	; skip if doesn't start with "."
		jne	WildNoDir
		cmp	byte ptr [si+1],0	; check for "."
		je	WildNameNext
		cmp	word ptr [si+1],'.'	; check for ".."
		je	WildNameNext
WildNoDir:
endif

		inc	word ptr wild_argc
		les	di, dword ptr wild_destin
		mov	cx, wild_path_len	; prefix filename with path
		jcxz	WildCopyName
		lds	si, dword ptr wild_argument
WildCopyPath:	lodsb
		call	ArgPushChar
		loop	WildCopyPath
WildCopyName:	lea	si,wild_ffblk.ff_name	; copy filename from ffblk
WildNameLoop:	lods	byte ptr ss:[si]
		push	ax
		call	ArgPushChar		; store char in destination
		pop	ax
		and	al, al			; continue until \0
		jnz	WildNameLoop
		mov	wild_destin, di
WildNameNext:	mov	ah, 4fh
		int	21h			; find next matching file
		jnc	WildAddArg
;
; Done with expansion. Restore ES:DI, set CX, and return.
;
WildDone:	mov	cx, wild_argc
		les	di, dword ptr wild_destin
		pop	ds
		ret

WildExpand	endp

;------------------------------------------------------------------------------
;
; Routine to store a character in the destination string.
;
ArgPushChar	proc	near

		cmp	di, wild_buff_max	; space available ?
		jae	ArgMoreSpace
		stosb				; yes --> store character
		ret
;
; No more argument space. Grab some more memory through sbrk.
;
ArgMoreSpace:	push	ds
		push	es
		push	si
		push	di
		push	ax
		push	bx
		push	cx
		push	dx

ifndef	__HUGE__
		mov	ds, savedDS
endif
		mov	ax, wild_more_space
		add	wild_buff_size, ax	; bump allocated size
		add	wild_buff_max, ax	; bump end pointer
		push	ax
		call	sbrk@
		pop	cx
if	LDATA
		and	ax, dx
endif
		cmp	ax, -1
		je	NoArgSpace		; abort if not enough space

		pop	dx
		pop	cx
		pop	bx
		pop	ax
		pop	di
		pop	si
		pop	es
		pop	ds
		stosb				; store character
		ret

ArgPushChar	endp

;------------------------------------------------------------------------------
;
; Not enough space to process the command line .... abort.
;
NoArgSpace:	jmp	abort@

;------------------------------------------------------------------------------
;
; Routine to process an argument.
;
ProcessArg	proc	near

		push	bx
		xor	al, al
		call	ArgPushChar		; null-terminate
		pop	bx
		test	bh, 1			; wildcards present ?
		jnz	ArgWild
		inc	dx			; bump arg count
		ret
;
; We have a wildcard argument. Expand it.
;
ArgWild:	push	cx
		push	[si]			; save word following argument
		mov	byte ptr [si],0		; null-terminate argument
		xchg	si, wild_arg_src	; si = argument address
		push	di
		mov	di, wild_arg_dst
		push	dx
		call	WildExpand
		pop	dx
		pop	bx
		and	cx, cx			; see if any matched
		jnz	ArgWildSome
		mov	di, bx			; none ---> use unexpanded argument
		mov	cx, 1			; bump arg count by 1
ArgWildSome:	add	dx, cx
		mov	si, wild_arg_src
		pop	[si]			; restore word following argument
		pop	cx
		ret

ProcessArg	endp

;------------------------------------------------------------------------------
;
; Build the argv array. [DS:SI] is the expanded command line, CX its length.
; DX has the number of arguments (including the program name).
;
BuildArgv:	push	ds
		push	dx
		lds	dx, dword ptr wild_DTA_save
		mov	ah, 1ah
		int	21h			; switch to original DTA
		pop	dx
		pop	ds

		add	sp, wild_frame_size	; remove local variables

		mov	es,savedDS
		mov	es:[_argc@], dx
		inc	dx			; argv ends with a NULL pointer
		shl	dx, 1			;   argc * 2	(LDATA = 0)
IF	LDATA
		shl	dx, 1			;   argc * 4	(LDATA = 1)
ENDIF
		mov	bx, sp			; point to program name
		mov	bp, sp
		sub	bp, dx
		jb	NoArgSpace
		mov	sp, bp			; SS:BP = argv array address
		mov	word ptr es:[_argv@], bp
IF	LDATA
		mov	word ptr es:[_argv@+2], ss
ENDIF
		mov	[bp], bx		; set argv[0] to program name
IF	LDATA
		mov	[bp+2], ss		; program name is on the stack
ENDIF
		add	bp, dPtrSize

SetArgvX	label	near
		jcxz	SetLastArg
		mov	[bp], si		; Set argv[n]
IF	LDATA
		mov	[bp+2], ds
ENDIF
		add	bp, dPtrSize
CopyArg		label	near
		lodsb
		or	al, al
		loopnz	CopyArg
		jz	SetArgvX
SetLastArg	label	near
		xor	ax, ax
		mov	[bp], ax
IF	LDATA
		mov	[bp+2], ax
ENDIF
		mov	ds, savedDS

;==============================================================================
else
;==============================================================================

		mov	ds, bp
		xchg	si, dx		; DS: SI = Command Line address
		xchg	bx, cx		; CX = Command Line size including \r
		mov	ax, bx
		mov	dx, ax		; AX = BX = DX = 0
		inc	bx		; BX = Nb of arguments (at least 1)
Processing	label	near
		call	NextChar
		ja	NotQuote	; Not a quote and there are more
InString	label	near
		jb	BuildArgv	; Command line is empty now
		call	NextChar
		ja	InString	; Not a quote and there are more
NotQuote	label	near
		cmp	al, ' '
		je	EndArgument	; Space is an argument separator
		cmp	al, 13
		je	EndArgument	; \r	is an argument separator
		cmp	al, 9
		jne	Processing	; \t	is an argument separator
EndArgument	label	near
		xor	al, al		; Space and TAB are argument separators
		jmp	short Processing

;	Character test function used in SetArgs
;		On entry AL holds the previous character
;		On exit	 AL holds the next character
;			 ZF on if the next character is quote (") and AL = 0
;			 CF on if end of command line and AL = 0

NextChar	PROC	NEAR
		or	ax, ax
		jz	NextChar0
		inc	dx		; DX = Actual length of CmdLine
		stosb
		or	al, al
		jnz	NextChar0
		inc	bx		; BX = Number of parameters
NextChar0	label	near
		xchg	ah, al
		xor	al, al
		stc
		jcxz	NextChar2	; End of command line --> CF ON
		lodsb
		dec	cx
		sub	al, '"'
		jz	NextChar2	; Quote found --> AL = 0 and ZF ON
		add	al, '"'
		cmp	al,'\'
		jne	NextChar1	; It is not a \
		cmp	byte ptr ds:[si], '"'
		jne	NextChar1	; Only " is transparent after \
		lodsb
		dec	cx
NextChar1	label	near
		or	si, si		; Be sure both CF & ZF are OFF
NextChar2	label	near
		ret
NextChar	ENDP

;	Invalid program name

BadProgName	label	near
		jmp	abort@

;	Now, build the argv array

BuildArgv	label	near
		pop	cx
		add	cx, dx		; CX = Argument area size
		mov	ds, SavedDS
		mov	_argc@, bx
		inc	bx		; argv ends with a NULL pointer
		add	bx, bx		;	 argc * 2	(LDATA = 0)
IF	LDATA
		add	bx, bx		;	 argc * 4	(LDATA = 1)
ENDIF
		mov	si, sp
		mov	bp, sp
		sub	bp, bx
		jb	BadProgName
		mov	sp, bp		; SS:BP = argv array address
		mov	word ptr _argv@, bp
IF	LDATA
		mov	word ptr _argv@+2, ss
ENDIF
SetArgvX	label	near
		jcxz	SetLastArg
		mov	[bp], si	; Set argv[n]
IF	LDATA
		mov	[bp+2], ss
ENDIF
		add	bp, dPtrSize
CopyArg		label	near
		lods	byte ptr ss:[si]
		or	al, al
		loopnz	CopyArg
		jz	SetArgvX
SetLastArg	label	near
		xor	ax, ax
		mov	[bp], ax
IF	LDATA
		mov	[bp+2], ax
ENDIF

;==============================================================================
endif		;	ifdef WILD
;==============================================================================

;	Restore caller context and exit

IF	LPROG
		jmp	dword ptr SavedReturn
ELSE
		jmp	word ptr SavedReturn
ENDIF

ifdef	WILD
EndProc@	_wildargv, __CDECL__
else
EndProc@	_setargv, __CDECL__
endif

CSegEnd@
	END

⌨️ 快捷键说明

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