944,051 Members | Top Members by Rank

Ad:
0

Command line parser

by on Feb 9th, 2005
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
Assembly Code Snippet (Toggle Plain Text)
  1. ; *** PARSE COMMAND LINE ***
  2.  
  3. ; ENTRY: ESP + 4 > Points to callers bottom of stack
  4.  
  5. ; LEAVE: ESP > Points to address of array of string pointers
  6. ; AL > Number of parameters passed to application
  7. ; AH > Bit 0 = 1 If mismatched quotes, Bit 1 = 1, if array overflow.
  8.  
  9. ; NOTE: As this routine modifies ESP,it is important calling routine take appropriate
  10. ; measures to account for this fact.
  11.  
  12. ; Routine modifies original string, it is important ParseCL only be called once.
  13.  
  14. ParseCL pop eax ; Get callers return.
  15.  
  16. ; Allocate 512 bytes from stack for a maximum of 128 32 bit pointers to strings. Max
  17. ; value for ECX is 1020 due to the 8 bit unsigned value returned in AL.
  18.  
  19. mov ecx, 512
  20. sub esp, ecx
  21. mov edx, esp ; Needed later for base pointer.
  22. push eax ; Callers return to top of stack again.
  23.  
  24. push esi
  25. push edi ; Save essential registers
  26. push ebx
  27.  
  28. ; Initialize pointers and data required by parsing loop
  29.  
  30. mov ebx, edx ; EBX = Base of parameter pointers
  31. call _GetCommandLineA@0
  32. mov esi, eax
  33. mov edi, eax
  34. mov edx, ecx
  35. shr edx, 2 ; EDX = Number of pointers that can be saved.
  36. xor ecx, ecx
  37. mov eax, ecx
  38. cld ; Assure STOS & LODS will auto-inc indices.
  39.  
  40. .NextCh mov ah, al ; Save previously read character
  41. lodsb ; Get character from source
  42. and al, al ; Is it NULL (termination byte)
  43. jz .Done ; ZR = 1, if finished
  44.  
  45. ; Quotation marks have a special meaning as that inside quotes the other delimiting
  46. ; character being the space are to be treated as literal. Toggle bit 16 in EAX to
  47. ; indicate this, and if bit 16 is on upon return we know there were mismatched quotes.
  48.  
  49. cmp al, '"'
  50. jnz .Space ; ZR = 0, if it wasn't a quotation mark
  51.  
  52. xor al, al ; Quotes are always converted to null
  53. btc eax, 16 ; Toggle InQuotes flag
  54. jnc .NextCh ; Pass over if it's leading quote
  55.  
  56. .Post stosb
  57. jmp short .NextCh
  58.  
  59. ; Spaces are the other delimiter and except when inside quotes are to be treated as
  60. ; end of string. NOTE: Embedded spaces may cause paramter to be misiterpreted.
  61.  
  62. .Space cmp al, ' '
  63. jnz .Default ; ZR = 0, if this is not a space
  64.  
  65. bt eax, 16 ; Are we inside quotation marks
  66. jc .Post ; NC = 1, if in quotes
  67.  
  68. xor al, al ; Nullify character
  69. and ah, ah ; Determine if previous character is null
  70. jz .NextCh ; Ignore leading spaces
  71. jmp short .Post
  72.  
  73. ; All other characters are treated literaly, and if the previous character (AH) is null
  74. ; then we know this is the begining of the next parameter
  75.  
  76. .Default and ah, ah
  77. jnz .Post ; Not first character of parameter
  78.  
  79. ; Check value of CX versus DX which is the maximum number of pointers that can be save
  80. ; in allocated stack space.
  81.  
  82. cmp cx, dx
  83. ja .NoRoomLeft
  84.  
  85. mov [ebx + ecx * 4], edi ; Save pointer
  86. inc ecx
  87. jmp short .Post
  88.  
  89. .NoRoomLeft bts eax, 17 ; Set error condition, buffer overflow
  90. jmp short .Done + 2
  91.  
  92. .Done stosb
  93.  
  94. ; Establish return value in EAX, by shifting status bits 16 & 17 into 8 & 9 and then
  95. ; moving number of parameters passed into AL, resulting in AX being retunred value
  96.  
  97. shr eax, 8 ; Shift Status bits
  98. mov al, cl ; Parameters passed into AL
  99.  
  100. ; Stack space must be compressed so last parameters pointer is on top of callers stack.
  101.  
  102. add ecx, 4 ; Account for values on stack already
  103. sub edx, ecx ; Offset from maximum allowable
  104. shl edx, 2 ; Determine actual number of bytes
  105. add edx, ebx ; EDX = Offset from top of callers stack
  106.  
  107. ; Initialize indexes with appropriate values for block move MOVSD and move block.
  108.  
  109. mov edi, edx
  110. mov esi, esp
  111. rep movsd
  112. mov esp, edx ; Now stack pointer can be relocated
  113.  
  114. ; Restore all register and return to caller with appropriate pointers on stack
  115.  
  116. pop ebx
  117. pop edi
  118. pop esi
  119. ret
Comments on this Code Snippet
Feb 9th, 2005
0

Re: Command line parser

Should be moved to asm
DaniWeb's Hypocrite
vegaseat is offline Offline
5,792 posts
since Oct 2004
Feb 9th, 2005
0

Re: Command line parser

Looks like it was
The Queen of DaniWeb
cscgal is online now Online
13,646 posts
since Feb 2002
Message:
Previous Thread in Assembly Forum Timeline: Does anyone out there know Assembler?!!!
Next Thread in Assembly Forum Timeline: Application startup & Message Pump





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC