Command line parser

Tight_Coder_Ex 0 Tallied Votes 209 Views Share

As part of a larger hobby project that I'm undertaking being a doubly linked list for 95/98/XP, this is the first in a series that I will be posting.

Upon completion, I will have a complete application written in assembly for the Windows platform. Compiled with NASM

; 				     *** PARSE COMMAND LINE ***

;	ENTRY:	ESP + 4 > Points to callers bottom of stack

;	LEAVE:	ESP	> Points to address of array of string pointers
;		 AL	> Number of parameters passed to application
;		 AH	> Bit 0 = 1 If mismatched quotes, Bit 1 = 1, if array overflow.

; NOTE: As this routine modifies ESP,it is important calling routine take appropriate
;	measures to account for this fact.

;	Routine modifies original string, it is important ParseCL only be called once.

  ParseCL	pop	eax			; Get callers return.

	; Allocate 512 bytes from stack for a maximum of 128 32 bit pointers to strings. Max
	; value for ECX is 1020 due to the 8 bit unsigned value returned in AL.

		mov	ecx, 512
		sub	esp, ecx
		mov	edx, esp		; Needed later for base pointer.
		push	eax			; Callers return to top of stack again.

		push	esi
		push	edi			; Save essential registers
		push	ebx

	; Initialize pointers and data required by parsing loop

		mov	ebx, edx		; EBX = Base of parameter pointers
		call	_GetCommandLineA@0
		mov	esi, eax
		mov	edi, eax
		mov	edx, ecx
		shr	edx, 2			; EDX = Number of pointers that can be saved.
		xor	ecx, ecx
		mov	eax, ecx
		cld				; Assure STOS & LODS will auto-inc indices.

  .NextCh	mov	 ah,  al		; Save previously read character
		lodsb				; Get character from source
		and	 al,  al		; Is it NULL (termination byte)
		jz	.Done			; ZR = 1, if finished

	; Quotation marks have a special meaning as that inside quotes the other delimiting
	; character being the space are to be treated as literal.  Toggle bit 16 in EAX to
	; indicate this, and if bit 16 is on upon return we know there were mismatched quotes.

		cmp	 al, '"'
		jnz	.Space			; ZR = 0, if it wasn't a quotation mark

		xor	 al, al			; Quotes are always converted to null
		btc	eax, 16			; Toggle InQuotes flag
		jnc	.NextCh			; Pass over if it's leading quote

  .Post		stosb
		jmp	short	.NextCh

	; Spaces are the other delimiter and except when inside quotes are to be treated as 
	; end of string.  NOTE: Embedded spaces may cause paramter to be misiterpreted.

  .Space	cmp	 al, ' '
		jnz	.Default		; ZR = 0, if this is not a space

		bt	eax, 16			; Are we inside quotation marks
		jc	.Post			; NC = 1, if in quotes

		xor	 al,  al		; Nullify character
		and	 ah,  ah		; Determine if previous character is null
		jz	.NextCh			; Ignore leading spaces
		jmp	short .Post

	; All other characters are treated literaly, and if the previous character (AH) is null
	; then we know this is the begining of the next parameter

  .Default	and	 ah,  ah
		jnz	.Post			; Not first character of parameter

	; Check value of CX versus DX which is the maximum number of pointers that can be save
	; in allocated stack space.

		cmp	 cx,  dx
		ja	.NoRoomLeft

		mov	[ebx + ecx * 4], edi	; Save pointer
		inc	ecx
		jmp	short .Post

  .NoRoomLeft	bts	eax, 17			; Set error condition, buffer overflow
		jmp	short .Done + 2

  .Done		stosb

	; Establish return value in EAX, by shifting status bits 16 & 17 into 8 & 9 and then
	; moving number of parameters passed into AL, resulting in AX being retunred value

		shr	eax, 8			; Shift Status bits
		mov	 al,  cl		; Parameters passed into AL

	; Stack space must be compressed so last parameters pointer is on top of callers stack.

		add	ecx, 4			; Account for values on stack already
		sub	edx, ecx		; Offset from maximum allowable
		shl	edx, 2			; Determine actual number of bytes
		add	edx, ebx		; EDX = Offset from top of callers stack

	; Initialize indexes with appropriate values for block move MOVSD and move block.

		mov	edi, edx
		mov	esi, esp
		rep	movsd
		mov	esp, edx		; Now stack pointer can be relocated

	; Restore all register and return to caller with appropriate pointers on stack

		pop	ebx
		pop	edi
		pop	esi
		ret
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Should be moved to asm

Dani 4,084 The Queen of DaniWeb Administrator Featured Poster Premium Member

Looks like it was :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.