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

📄 setargv.asm

📁 著名的C语言编辑器
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	NAME	SETARGV
	PAGE	60,132
;[]------------------------------------------------------------[]
;|	SETARGV.ASM -- Parse Command Line			|
;|								|
;|	Turbo-C Run Time Library	version 2.0		|
;|								|
;|	Copyright (c) 1987,1988 by Borland International Inc.	|
;|	All Rights Reserved.					|
;[]------------------------------------------------------------[]

	INCLUDE RULES.ASI

;	Segment and Group declarations

Header@

;	External references

ExtSym@		_argc, WORD, __CDECL__
dPtrExt@	_argv, __CDECL__
ExtSym@		_psp, WORD, __CDECL__
ExtSym@		_envseg, WORD, __CDECL__
ExtSym@		_envLng, WORD, __CDECL__
ExtSym@		_osmajor, BYTE, __CDECL__
ExtProc@	abort, __CDECL__

ifdef	WILD
ExtProc@	sbrk, __CDECL__
endif

	SUBTTL	Parse Command Line
	PAGE
;/*							*/
;/*-----------------------------------------------------*/
;/*							*/
;/*	Parse Command Line				*/
;/*	------------------				*/
;/*							*/
;/*-----------------------------------------------------*/
;/*							*/
PSPCmd		equ	00080h

CSeg@

IF	LPROG
SavedReturn	dd	?
ELSE
SavedReturn	dw	?
ENDIF
SavedDS		dw	?
SavedBP		dw	?


ifdef	WILD

;------------------------------------------------------------------------------
;
; Not enough space on stack for the program name.
;
BadProgName	label	near
		jmp	abort@

endif

;==============================================================================

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

;	First, save caller context and Return Address

		pop	word ptr SavedReturn
IF	LPROG
		pop	word ptr SavedReturn+2
ENDIF
		mov	SavedDS, ds
		cld

;	Compute Command Line size

		mov	es, _psp@
		mov	si, PSPCmd	; ES: SI = Command Line address
		xor	ah, ah
		lods	byte ptr es:[si]
		inc	ax		; AX = Command Line size including \r
		mov	bp, es
		xchg	dx, si		; BP:DX = Command Line address
		xchg	bx, ax		; BX	= Command line size

;	Compute Program Name size

		mov	si, _envLng@
		add	si, 2		; SI = Program name offset
		mov	cx, 1		; CX = Filename size (includes \0)
		cmp	_osmajor@, 3
		jb	NoProgramName
		mov	es, _envseg@
		mov	di, si		; SI = argv[0] address
		mov	cl, 07fh
		xor	al, al
		repnz	scasb
		jcxz	BadProgName
		xor	cl, 07fh	; CX = Filename size (includes \0)
NoProgramName	label	near

;	Reserve space for the arguments

		sub	sp, 2		; To be sure nothing in SS:FFFF
		mov	ax, 1
ifndef	WILD
		add	ax, bx
endif
		add	ax, cx
		and	ax, not 1
		mov	di, sp
		sub	di, ax
		jb	BadProgName
		mov	sp, di		; SS:DI = Command Line storage address

;	Copy ProgName to the stack

		mov	ax, es
		mov	ds, ax
		mov	ax, ss
		mov	es, ax
ifndef	WILD
		push	cx
endif
		dec	cx
		rep	movsb
		xor	al, al
		stosb			; ASCIIZ string

;	Process Command Line.

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

;
; The value of "wild_attr" is used in the "findfirst" call as the file
; attribute.
;
; The default value is 0, which will only include "regular" files.
;
; Adding 10H to this value will include directories, 04h will include system
; files, and 02h will include hidden files.
;

wild_attr	equ	0			; include only regular files

;------------------------------------------------------------------------------

ffblk		struc

ff_reserved	db	21 dup (?)
ff_attrib	db	?
ff_ftime	dw	?
ff_fdate	dw	?
ff_fsize	dd	?
ff_name		db	14 dup (?)

ffblk		ends

wild_init_space	equ	128			; initial buffer allocation
wild_more_space	equ	256			; buffer size increment

;------------------------------------------------------------------------------

wild_buff_addr	equ	[bp]
wild_buff_size	equ	[bp+4]
wild_buff_max	equ	[bp+6]
wild_arg_src	equ	[bp+8]
wild_arg_dst	equ	[bp+10]

wild_argument	equ	[bp+12]
wild_destin	equ	[bp+16]
wild_path_len	equ	[bp+20]
wild_argc	equ	[bp+22]

wild_DTA_save	equ	[bp+24]
wild_ffblk	equ	[bp+28]

wild_frame_size	equ	28 + TYPE ffblk

;------------------------------------------------------------------------------

		mov	cx, bp			; save segment of command line
		dec	bx			; don't need trailing \0

		sub	sp, wild_frame_size
		mov	bp, sp			; bp points at local variables

		push	dx			; save cmd line addr
		push	cx			; save cmd line seg
		push	bx			; save cmd line size
		mov	ax, wild_init_space
		mov	wild_buff_size, ax	; save initial size
ifndef	__HUGE__
		mov	ds, savedDS
endif
		push	ax
		call	sbrk@
		pop	cx			; toss parameter
		pop	cx			; restore cmd line size
		pop	ds			; restore cmd line seg
		pop	si			; restore cmd line addr

		mov	wild_buff_addr, ax	; save offset
if	LDATA
		mov	wild_buff_addr+2, dx	; save segment
		and	ax, dx
else
		mov	wild_buff_addr+2, ss	; seg = SS
endif
		cmp	ax, -1
		je	NoSbrkSpace		; abort if not enough space
		add	ax, wild_buff_size
		mov	wild_buff_max, ax	; save max offset

		mov	ah, 2fh
		int	21h			; get current DTA
		mov	wild_DTA_save, bx
		mov	wild_DTA_save+2, es
		push	ds
		push	ss			; fflbk is on stack
		pop	ds
		lea	dx, wild_ffblk
		mov	ah, 1ah
		int	21h			; switch DTA to ffblk
		pop	ds

		les	di, dword ptr wild_buff_addr
		xor	dx, dx			; dx = # of arguments
;
; Start new argument.
;
NewArg:		mov	wild_arg_dst, di
		xor	bh, bh			; bh = wildcard flag
;
; Skip leading whitespace.
;
ArgCopy:	mov	wild_arg_src, si	; save address of argument
		call	GetChar
		jc	ArgCopyDone		; jump if no more characters
		jz	ArgCopyLoop
		cmp	al, ' '
		je	ArgCopy			; skip whitespace
		cmp	al, 9
		je	ArgCopy
		cmp	al, 13
		je	ArgCopy
		cmp	al, '"'
		je	ArgQuote		; jump if quoted string
;
; Loop to copy unquoted argument.
;
ArgCopyLoop:	call	ArgPushChar		; store character in destination
		call	GetChar
		jc	ArgComplete		; jump if end of line
		jz	ArgCopyLoop		; jump if \"
		cmp	al, ' '
		je	ArgComplete		; whitespace terminates
		cmp	al, 9
		je	ArgComplete
		cmp	al, 13
		je	ArgComplete		; whitespace terminates
		cmp	al, '"'
		jne	ArgCopyLoop
ArgComplete:	call	ProcessArg		; copy or expand argument
		jmp	SHORT NewArg

NoSbrkSpace:	jmp	abort@			; error jump

;
; Here if quoted argument.
;
ArgQuote:	call	GetChar
		jc	QuoteDone
		jz	QuoteNext
		cmp	al, '"'			; terminating quote ?
		je	QuoteDone
QuoteNext:	call	ArgPushChar		; store character in destination
		jmp	SHORT ArgQuote
;
; End of a quoted argument. Push terminating null, do not expand.
;
QuoteDone:	xor	al, al
		call	ArgPushChar		; push terminating null
		inc	dx			; bump arg count
		jmp	SHORT NewArg		; go get more

;------------------------------------------------------------------------------
;
; Here when done expanding command line. Go build the argv array.
;
ArgCopyDone:	mov	ax, di			; ax = unused space
		sub	ax, wild_buff_max
		jz	ArgNoWaste		; skip if all used
		push	dx
		push	di
ifndef	__HUGE__
		mov	ds, savedDS
endif
		push	ax
		call	sbrk@			; release unused memory
		pop	cx			; toss parameter
		pop	di
		pop	dx
ArgNoWaste:	lds	si, dword ptr wild_buff_addr
		mov	cx, di
		sub	cx, si			; cx = number of bytes in expanded line
		inc	dx			; count program name
		jmp	BuildArgv

;------------------------------------------------------------------------------
;
; Routine to retrieve the next character from the command line.
;	Sets CF when end of line reached.
;	Sets ZF when \ character found (i.e. \")
;
;	bh.bit0 set if wildcard chars found (* or ?)
;	bh.bit1 set if \ character found (\")
;
GetChar		proc	near

		jcxz	GchEnd			; jump if no more
		lodsb
		dec	cx
		cmp	al, '\'			; escape ?
		je	GchEsc
		cmp	al, '?'
		je	GchWild
		cmp	al, '*'
		je	GchWild
GchRet:		or	ah, 1			; clear CF and ZF
		ret
GchWild:	test	bh, bh
		jnz	GchRet			; give up if \" has been found
		or	bh, 1
		ret
GchEsc:		jcxz	GchRet			; check for \ at end of line
		cmp	byte ptr [si],'"'
		jne	GchRet			; only \" is special
		lodsb
		dec	cx
		mov	bh, 2			; set \ flag
		xor	ah, ah			; clear CF, set ZF
		ret
GchEnd:		stc
		ret

GetChar		endp

;------------------------------------------------------------------------------
;
; Routine to expand a wildcard parameter.
;
;	DS:SI	=	argument address
;	ES:DI	=	destination
; Returns:

⌨️ 快捷键说明

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