I disassembled some executables using PE Explorer and reverse engineered how command line parameters are parsed.
I then wrote a paper How Command Line Parameters Are Parsed
;---------------------------------------------------------------------------------------------------- 00406738 CCCCCCCCCCCCCCCC Align 16 00406740 SUB_L00406740: ;PARSE COMMAND LINE PARAMETERS 00406740 55 push ebp 00406741 8BEC mov ebp,esp 00406743 83EC14 sub esp,00000014h 00406746 8B4518 mov eax,[ebp+18h] ;argc count. [ebp+18h] is pointer to a counter 00406749 C70000000000 mov dword ptr [eax],00000000h ;start argc counter = 0 0040674F 8B4D14 mov ecx,[ebp+14h] 00406752 C70101000000 mov dword ptr [ecx],00000001h ;start +14h counter = 1 00406758 8B5508 mov edx,[ebp+08h] ;pointer to command line 0040675B 8955FC mov [ebp-04h],edx ;local storage for pointer into command line 0040675E 837D0C00 cmp dword ptr [ebp+0Ch],00000000h ;[ebp+0Ch] is pointer into argv[] array of pointers 00406762 7411 +--jz L00406775 00406764 8B450C | mov eax,[ebp+0Ch] ;[ebp+0Ch] is pointer into argv[] array of pointers 00406767 8B4D10 | mov ecx,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 0040676A 8908 | mov [eax],ecx 0040676C 8B550C | mov edx,[ebp+0Ch] ;pointer into argv[] array of pointers 0040676F 83C204 | add edx,00000004h 00406772 89550C v mov [ebp+0Ch],edx 00406775 L00406775: 00406775 8B45FC mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406778 0FBE08 movsx ecx,[eax] 0040677B 83F922 cmp ecx,00000022h ; " 0040677E 0F85C9000000 +<---------------------jnz L0040684D ;jump if we don't have a " | | ;COMMAND LINE BEGINS WITH A " | ;parse off the 0th parameter (program filename) enclosed in "". No special handling for backslashes? 00406784 | +------->L00406784: 00406784 8B55FC | ^ mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406787 83C201 | | add edx,00000001h ;increment pointer into command line. Move to next character 0040678A 8955FC | | mov [ebp-04h],edx 0040678D 8B45FC | | mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406790 0FBE08 | | movsx ecx,[eax] ;next character 00406793 83F922 | | cmp ecx,00000022h ; " 00406796 747A | | +<------------jz L00406812 ;jump if we have a closing " (command line begins "", or "C:\test a\MyProgram.exe") 00406798 8B55FC | | | mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 0040679B 0FBE02 | | | movsx eax,[edx] 0040679E 85C0 | | | test eax,eax ;end of command line? (command line is a single ". count it as an empty parameter) 004067A0 7470 | | +<------------jz L00406812 ;jump if end of command line 004067A2 8B4DFC | | | mov ecx,[ebp-04h] ;[ebp-04h] is pointer into command line. 004067A5 33D2 | | | xor edx,edx 004067A7 8A11 | | | mov dl,[ecx] 004067A9 33C0 | | | xor eax,eax 004067AB 8A82C1A04200 | | | mov al,[edx+L0042A0C1] 004067B1 83E004 | | | and eax,00000004h 004067B4 85C0 | | | test eax,eax ;testing a flag 004067B6 742F | | | +--jz L004067E7 004067B8 8B4D18 | | | | mov ecx,[ebp+18h] ;argc count. [ebp+18h] is pointer to a counter 004067BB 8B11 | | | | mov edx,[ecx] 004067BD 83C201 | | | | add edx,00000001h ;increment argc counter 004067C0 8B4518 | | | | mov eax,[ebp+18h] ;[ebp+18h] is pointer to a counter 004067C3 8910 | | | | mov [eax],edx 004067C5 837D1000 | | | | cmp dword ptr [ebp+10h],00000000h ;check for no parameters string 004067C9 741C | | | +--jz L004067E7 004067CB 8B4D10 | | | | mov ecx,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 004067CE 8B55FC | | | | mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 004067D1 8A02 | | | | mov al,[edx] ;copy over character to parameters string 004067D3 8801 | | | | mov [ecx],al 004067D5 8B4D10 | | | | mov ecx,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 004067D8 83C101 | | | | add ecx,00000001h ;move to next character 004067DB 894D10 | | | | mov [ebp+10h],ecx 004067DE 8B55FC | | | | mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 004067E1 83C201 | | | | add edx,00000001h ;move to next character 004067E4 8955FC | | | v mov [ebp-04h],edx 004067E7 | | | L004067E7: 004067E7 8B4518 | | | mov eax,[ebp+18h] ;argc count. [ebp+18h] is pointer to a counter 004067EA 8B08 | | | mov ecx,[eax] 004067EC 83C101 | | | add ecx,00000001h ;increment argc counter 004067EF 8B5518 | | | mov edx,[ebp+18h] 004067F2 890A | | | mov [edx],ecx 004067F4 837D1000 | | | cmp dword ptr [ebp+10h],00000000h ;check for end of string. [ebp+10h] is pointer into some string we read 004067F8 7413 | | | +--jz L0040680D 004067FA 8B4510 | | | | mov eax,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 004067FD 8B4DFC | | | | mov ecx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406800 8A11 | | | | mov dl,[ecx] 00406802 8810 | | | | mov [eax],dl 00406804 8B4510 | | | | mov eax,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 00406807 83C001 | | | | add eax,00000001h 0040680A 894510 | | | v mov [ebp+10h],eax 0040680D | | | L0040680D: 0040680D E972FFFFFF | +<-----|-------------jmp L00406784 ;BACK TO TOP | | | | 00406812 | +-L00406812:->;Command line enclosed in "...", or command line started with " and later abruptly ended with no closing ") 00406812 8B4D18 | mov ecx,[ebp+18h] ;argc count. First parameter is NULL ("" or single ") 00406815 8B11 | mov edx,[ecx] 00406817 83C201 | add edx,00000001h ;increment counter 0040681A 8B4518 | mov eax,[ebp+18h] ;character counter 0040681D 8910 | mov [eax],edx 0040681F 837D1000 | cmp dword ptr [ebp+10h],00000000h ;check for no parameters string (we build string param1<\x00>param2<\x00>param3<\x00>...) 00406823 740F | +--jz L00406834 00406825 8B4D10 | | mov ecx,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 00406828 C60100 | | mov byte ptr [ecx],00h ;terminate this parameter (i.e. begin parameter string series with a \x00 indicating first parameter is NULL) 0040682B 8B5510 | | mov edx,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 0040682E 83C201 | | add edx,00000001h 00406831 895510 | v mov [ebp+10h],edx 00406834 | L00406834: 00406834 8B45FC | mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406837 0FBE08 | movsx ecx,[eax] 0040683A 83F922 | cmp ecx,00000022h ; closing " or end of command line? 0040683D 7509 | +--jnz L00406848 0040683F 8B55FC | | mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406842 83C201 | | add edx,00000001h ;move to next character after " 00406845 8955FC | v mov [ebp-04h],edx 00406848 | L00406848: 00406848 E9CF000000 | +<---------------- jmp L0040691C | | | | v | 0040684D +-->|----->L0040684D: ; we don't have a " 0040684D 8B4518 ^ | mov eax,[eb*p+18h] ;argc counter 00406850 8B08 | | mov ecx,[eax] 00406852 83C101 | | add ecx,00000001h ;increment argc counter 00406855 8B5518 | | mov edx,[ebp+18h] ;counter 00406858 890A | | mov [edx],ecx 0040685A 837D1000 | | cmp dword ptr [ebp+10h],00000000h ;check for end of string. [ebp+10h] is pointer into some string we read 0040685E 7413 | | +--jz L00406873 00406860 8B4510 | | | mov eax,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 00406863 8B4DFC | | | mov ecx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406866 8A11 | | | mov dl,[ecx] 00406868 8810 | | | mov [eax],dl 0040686A 8B4510 | | | mov eax,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 0040686D 83C001 | | | add eax,00000001h ;move to next character 00406870 894510 | | v mov [ebp+10h],eax 00406873 | | L00406873: 00406873 8B4DFC | | mov ecx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406876 8A11 | | mov dl,[ecx] 00406878 8855F4 | | mov [ebp-0Ch],dl 0040687B 8B45FC | | mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 0040687E 83C001 | | add eax,00000001h ;move to next character 00406881 8945FC | | mov [ebp-04h],eax 00406884 8B4DF4 | | mov ecx,[ebp-0Ch] 00406887 81E1FF000000 | | and ecx,000000FFh 0040688D 33D2 | | xor edx,edx 0040688F 8A91C1A04200 | | mov dl,[ecx+L0042A0C1] 00406895 83E204 | | and edx,00000004h 00406898 85D2 | | test edx,edx 0040689A 742F | | +-------------jz L004068CB 0040689C 8B4518 | | | mov eax,[ebp+18h] ;argc count. counter 0040689F 8B08 | | | mov ecx,[eax] 004068A1 83C101 | | | add ecx,00000001h ;increment argc counter 004068A4 8B5518 | | | mov edx,[ebp+18h] ;counter 004068A7 890A | | | mov [edx],ecx 004068A9 837D1000 | | | cmp dword ptr [ebp+10h],00000000h ;check for end of string. [ebp+10h] is pointer into some string we read 004068AD 7413 | | | +--jz L004068C2 004068AF 8B4510 | | | | mov eax,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 004068B2 8B4DFC | | | | mov ecx,[ebp-04h] ;[ebp-04h] is pointer into command line. 004068B5 8A11 | | | | mov dl,[ecx] 004068B7 8810 | | | | mov [eax],dl 004068B9 8B4510 | | | | mov eax,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 004068BC 83C001 | | | | add eax,00000001h 004068BF 894510 | | | v mov [ebp+10h],eax 004068C2 | | | L004068C2: 004068C2 8B4DFC | | | mov ecx,[ebp-04h] ;[ebp-04h] is pointer into command line. 004068C5 83C101 | | | add ecx,00000001h ;move to next character 004068C8 894DFC | | | mov [ebp-04h],ecx 004068CB | | +>L004068CB: 004068CB 8B55F4 | | mov edx,[ebp-0Ch] 004068CE 81E2FF000000 | | and edx,000000FFh 004068D4 83FA20 | | cmp edx,00000020h ;{space} 004068D7 741E | | +<------------jz L004068F7 004068D9 8B45F4 | | | mov eax,[ebp-0Ch] 004068DC 25FF000000 | | | and eax,000000FFh 004068E1 85C0 | | | test eax,eax 004068E3 7412 | | +<------------jz L004068F7 004068E5 8B4DF4 | | | mov ecx,[ebp-0Ch] 004068E8 81E1FF000000 | | | and ecx,000000FFh 004068EE 83F909 | | | cmp ecx,00000009h ;{tab} 004068F1 0F8556FFFFFF +<--|----|-------------jnz L0040684D | | | v 004068F7 | +>L004068F7: ;end of parameter 004068F7 8B55F4 | mov edx,[ebp-0Ch] 004068FA 81E2FF000000 | and edx,000000FFh 00406900 85D2 | test edx,edx 00406902 750B | +--jnz L0040690F 00406904 8B45FC | | mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406907 83E801 | | sub eax,00000001h ;move to next character 0040690A 8945FC v | mov [ebp-04h],eax 0040690D EB0D +<------------- v--jmp L0040691C 0040690F | L0040690F: 0040690F 837D1000 v cmp dword ptr [ebp+10h],00000000h ;check for end of string. [ebp+10h] is pointer into some string we read 00406913 7407 +<-----------------jz L0040691C 00406915 8B4D10 | mov ecx,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 00406918 C641FF00 | mov byte ptr [ecx-01h],00h ;terminate string v 0040691C +----->L0040691C: 0040691C C745EC00000000 mov dword ptr [ebp-14h],00000000h v ;BEGIN NEXT PARAMETER v v 00406923 +--------->L00406923: ;begin next parameter 00406923 8B55FC | mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406926 0FBE02 | movsx eax,[edx] 00406929 85C0 | test eax,eax ;end of command line? 0040692B 7421 | +<--------------jz L0040694E ;jump if end of command line 0040692D | | +>L0040692D: ;skip over multiple spaces/tabs between parameters 0040692D 8B4DFC | | | mov ecx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406930 0FBE11 | | | movsx edx,[ecx] 00406933 83FA20 | | | cmp edx,00000020h ;{space} 00406936 740B | | | +--jz L00406943 00406938 8B45FC | | | | mov eax,[ebp-04h] 0040693B 0FBE08 | | | | movsx ecx,[eax] 0040693E 83F909 | | | | cmp ecx,00000009h ;{TAB} 00406941 750B | +<|--------- v--jnz L0040694E 00406943 | | | L00406943: 00406943 8B55FC | | | mov edx,[ebp-04h] 00406946 83C201 | | | add edx,00000001h ;move to next character 00406949 8955FC | | | mov [ebp-04h],edx 0040694C EBDF | | +<------------jmp L0040692D 0040694E | +-->L0040694E: ;start of next parameter 0040694E 8B45FC | mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406951 0FBE08 | movsx ecx,[eax] 00406954 85C9 | test ecx,ecx ;end of command line? 00406956 7505 | +--jnz L0040695D 00406958 E9DE010000 | v jmp L00406B3B ;end parsing parameters off command line 0040695D | L0040695D: ;start of next parameter 0040695D 837D0C00 | cmp dword ptr [ebp+0Ch],00000000h ;do we have a pointer into argv[] array of pointers? 00406961 7411 | +--jz L00406974 00406963 8B550C | | mov edx,[ebp+0Ch] ;pointer into argv[] array of pointers 00406966 8B4510 | | mov eax,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 00406969 8902 | | mov [edx],eax 0040696B 8B4D0C | | mov ecx,[ebp+0Ch] ;pointer into argv[] array of pointers 0040696E 83C104 | | add ecx,00000004h ;pointer to next argv[] vector 00406971 894D0C | v mov [ebp+0Ch],ecx 00406974 | L00406974: ;increment argc 00406974 8B5514 | mov edx,[ebp+14h] ;pointer to argc count 00406977 8B02 | mov eax,[edx] 00406979 83C001 | add eax,00000001h ;increment argc 0040697C 8B4D14 | mov ecx,[ebp+14h] 0040697F 8901 | mov [ecx],eax | ; | ; 00406981 |+-------->L00406981: ;PROCESS CURRENT COMMAND LINE CHARACTER 00406981 C745F801000000|| mov dword ptr [ebp-08h],00000001h ;Do not add this character to parameter? (1=add,0=skip) 00406988 C745F000000000|| mov dword ptr [ebp-10h],00000000h ;counter count number of backslashes 0040698F || +-L0040698F: ;COUNT NUMBER OF BACKSLASHES 0040698F 8B55FC || | mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406992 0FBE02 || | movsx eax,[edx] 00406995 83F85C || | cmp eax,0000005Ch ; \ 00406998 7514 || | +--jnz L004069AE 0040699A 8B4DFC || | | mov ecx,[ebp-04h] ;[ebp-04h] is pointer into command line. 0040699D 83C101 || | | add ecx,00000001h ;move to next character 004069A0 894DFC || | | mov [ebp-04h],ecx 004069A3 8B55F0 || | | mov edx,[ebp-10h] ;increment number of backslashes 004069A6 83C201 || | | add edx,00000001h 004069A9 8955F0 || | | mov [ebp-10h],edx 004069AC EBE1 || +<------------jmp L0040698F || | || v 004069AE || L004069AE: 004069AE 8B45FC || mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 004069B1 0FBE08 || movsx ecx,[eax] 004069B4 83F922 || cmp ecx,00000022h ; " 004069B7 7551 || +-----------------jnz L00406A0A || | ;WE HAVE A " preceeded by 0 or more \ 004069B9 8B45F0 || | mov eax,[ebp-10h] ;number of backslashes 004069BC 33D2 || | xor edx,edx 004069BE B902000000 || | mov ecx,00000002h 004069C3 F7F1 || | div ecx 004069C5 85D2 || | test edx,edx ;test for even/odd number of slashes 004069C7 7539 ||+--------------------jnz L00406A02 ;jump if odd. Else zero or an even number of backslashes. 004069C9 837DEC00 ||| | cmp dword ptr [ebp-14h],00000000h ;currently in a double quoted string? 004069CD 7420 ||| |+----------------jz L004069EF ;jump if not currently in a double quoted string 004069CF 8B55FC ||| || mov edx,[ebp-04h] ;in a double quoted string and we now have a " preceeded by 0 or an even number of \ 004069D2 0FBE4201 ||| || movsx eax,[edx+01h] 004069D6 83F822 ||| || cmp eax,00000022h ;is next character also a " ? 004069D9 750B ||| || +<-jnz L004069E6 ;jump if next char not also a " 004069DB 8B4DFC ||| || | mov ecx,[ebp-04h] ;in a double quoted string and we now have a "" preceeded by 0 or an even number of \ 004069DE 83C101 ||| || | add ecx,00000001h ;move to the 2nd " in "" 004069E1 894DFC ||| || | mov [ebp-04h],ecx 004069E4 EB07 ||| || +<----------<-jmp L004069ED 004069E6 ||| || | L004069E6| ;begin a double quoted part 004069E6 C745F800000000||| || | +->mov dword ptr [ebp-08h],00000000h ;Do not add this character to parameter. Double "" 004069ED ||| || | L004069ED: 004069ED EB07 ||| || ++-------------jmp L004069F6 004069EF ||| |+-|->L004069EF: ;begin a double quoted part 004069EF C745F800000000||| | | mov dword ptr [ebp-08h],00000000h ;Do not add this character to parameter. " and not currently in a double quoted string 004069F6 ||| | +->L004069F6: ;toggle flag we are beginning/ending a double quoted string (") 004069F6 33D2 ||| | xor edx,edx 004069F8 837DEC00 ||| | cmp dword ptr [ebp-14h],00000000h 004069FC 0F94C2 ||| | setz dl ;if -14h = 0, set it to 1. if -14h = 1, set it to zero. 004069FF 8955EC ||| | mov [ebp-14h],edx 00406A02 ||+------->L00406A02: ;calculate number of backslashes divided by 2 00406A02 8B45F0 || | mov eax,[ebp-10h] 00406A05 D1E8 || | shr eax,1 ;slashes divided by 2 00406A07 8945F0 || v mov [ebp-10h],eax ;slashes divided by 2 (result might be zero) 00406A0A || +---->L00406A0A: ;ADD BACKSLASHES 00406A0A 8B4DF0 || ^ mov ecx,[ebp-10h] ;number of backslashes to add 00406A0D 8B55F0 || | mov edx,[ebp-10h] ;number of backslashes 00406A10 83EA01 || | sub edx,00000001h ;number of backslashes - 1 00406A13 8955F0 || | mov [ebp-10h],edx ;number of backslashes - 1 00406A16 85C9 || | test ecx,ecx ;if zero backslashes left to add 00406A18 7424 || | +--------------jz L00406A3E 00406A1A 837D1000 || | | cmp dword ptr [ebp+10h],00000000h ;check for no pointer to current parameter we are building 00406A1E 740F || | | +--jz L00406A2F 00406A20 8B4510 || | | | mov eax,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 00406A23 C6005C || | | | mov byte ptr [eax],5Ch ; \ add a backslash to out parameter 00406A26 8B4D10 || | | | mov ecx,[ebp+10h] ;[ebp+10h] is pointer into current parameter we are building/read back 00406A29 83C101 || | | | add ecx,00000001h ;move to next character 00406A2C 894D10 || | | v mov [ebp+10h],ecx 00406A2F || | | L00406A2F: 00406A2F 8B5518 || | | mov edx,[ebp+18h] ;argc count. counter 00406A32 8B02 || | | mov eax,[edx] 00406A34 83C001 || | | add eax,00000001h ;increment argc counter 00406A37 8B4D18 || | | mov ecx,[ebp+18h] ;counter 00406A3A 8901 || | | mov [ecx],eax 00406A3C EBCC || +--|--------------jmp L00406A0A 00406A3E || +->L00406A3E: ;backslashes added 00406A3E 8B55FC || mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406A41 0FBE02 || movsx eax,[edx] 00406A44 85C0 || test eax,eax ;end of command line? 00406A46 741C || +--jz L00406A64 ;finish up 00406A48 837DEC00 || | cmp dword ptr [ebp-14h],00000000h ;are we in a double quoted parameter? 00406A4C 751B || +-----------|--jnz L00406A69 ;jump if yes. Else a space or tab ends this parameter. 00406A4E 8B4DFC || | | mov ecx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406A51 0FBE11 || | | movsx edx,[ecx] 00406A54 83FA20 || | | cmp edx,00000020h ;{space} 00406A57 740B || | +--jz L00406A64 ;space marks end of this parameter 00406A59 8B45FC || | | mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406A5C 0FBE08 || | | movsx ecx,[eax] 00406A5F 83F909 || | | cmp ecx,00000009h ;{tab} 00406A62 7505 || | v +jnz L00406A69 00406A64 || | L00406A64: | ;tab marks end of this parameter 00406A64 E9AB000000 || | +>|jmp L00406B14 ;finished parsing this parameter. Finish parameter. || | | 00406A69 || +->L00406A69: v ;ADD THIS CHARACTER TO OUR PARAMETER 00406A69 837DF800 || +cmp dword ptr [ebp-08h],00000000h ;Do not add this character to parameter? (1=add,0=skip) 00406A6D 0F8493000000 || +<-------------jz L00406B06 ;skip this character 00406A73 837D1000 || | cmp dword ptr [ebp+10h],00000000h ;do we have a parameters string? 00406A77 7454 || | +<-----------jz L00406ACD 00406A79 8B55FC || | | mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406A7C 33C0 || | | xor eax,eax 00406A7E 8A02 || | | mov al,[edx] ;add character to parameter 00406A80 33C9 || | | xor ecx,ecx 00406A82 8A88C1A04200 || | | mov cl,[eax+L0042A0C1] 00406A88 83E104 || | | and ecx,00000004h 00406A8B 85C9 || | | test ecx,ecx ;Double-byte? 00406A8D 7429 || | | +--jz L00406AB8 ;if Double-Byte, add another byte? 00406A8F 8B5510 || | | | mov edx,[ebp+10h] ;parameters string 00406A92 8B45FC || | | | mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406A95 8A08 || | | | mov cl,[eax] 00406A97 880A || | | | mov [edx],cl ;copy byte to parameters string 00406A99 8B5510 || | | | mov edx,[ebp+10h] 00406A9C 83C201 || | | | add edx,00000001h ;move to next char 00406A9F 895510 || | | | mov [ebp+10h],edx ;[ebp+10h] is pointer into current parameter we are building/read back 00406AA2 8B45FC || | | | mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406AA5 83C001 || | | | add eax,00000001h ;move to next character 00406AA8 8945FC || | | | mov [ebp-04h],eax 00406AAB 8B4D18 || | | | mov ecx,[ebp+18h] ;byte counter 00406AAE 8B11 || | | | mov edx,[ecx] 00406AB0 83C201 || | | | add edx,00000001h ;increment byte counter 00406AB3 8B4518 || | | | mov eax,[ebp+18h] ;counter 00406AB6 8910 || | | v mov [eax],edx 00406AB8 || | |L00406AB8: 00406AB8 8B4D10 || | | mov ecx,[ebp+10h] 00406ABB 8B55FC || | | mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406ABE 8A02 || | | mov al,[edx] 00406AC0 8801 || | | mov [ecx],al ;copy byte to parameters string 00406AC2 8B4D10 || | | mov ecx,[ebp+10h] 00406AC5 83C101 || | | add ecx,00000001h ;move to next char 00406AC8 894D10 || | | mov [ebp+10h],ecx ;[ebp+10h] is pointer into current parameter we are building/read back 00406ACB EB2C || | v +-jmp L00406AF9 00406ACD || | +L00406ACD:| 00406ACD 8B55FC || | | mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406AD0 33C0 || | | xor eax,eax 00406AD2 8A02 || | | mov al,[edx] 00406AD4 33C9 || | | xor ecx,ecx 00406AD6 8A88C1A04200 || | | mov cl,[eax+L0042A0C1] 00406ADC 83E104 || | | and ecx,00000004h 00406ADF 85C9 || | v test ecx,ecx ;Double-Byte ? test flag 00406AE1 7416 || | +--jz L00406AF9 00406AE3 8B55FC || | | mov edx,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406AE6 83C201 || | | add edx,00000001h 00406AE9 8955FC || | | mov [ebp-04h],edx 00406AEC 8B4518 || | | mov eax,[ebp+18h] ;counter 00406AEF 8B08 || | | mov ecx,[eax] 00406AF1 83C101 || | | add ecx,00000001h ;increment counter 00406AF4 8B5518 || | | mov edx,[ebp+18h] ;counter 00406AF7 890A || | v mov [edx],ecx 00406AF9 || | L00406AF9: 00406AF9 8B4518 || | mov eax,[ebp+18h] ;counter 00406AFC 8B08 || | mov ecx,[eax] 00406AFE 83C101 || | add ecx,00000001h ;increment byte counter 00406B01 8B5518 || | mov edx,[ebp+18h] ;counter 00406B04 890A || | mov [edx],ecx 00406B06 || +->L00406B06: 00406B06 8B45FC || mov eax,[ebp-04h] ;[ebp-04h] is pointer into command line. 00406B09 83C001 || add eax,00000001h ;move to next character 00406B0C 8945FC || mov [ebp-04h],eax 00406B0F E96DFEFFFF |+---------------------jmp L00406981 ;process next character 00406B14 | L00406B14: 00406B14 837D1000 | cmp dword ptr [ebp+10h],00000000h ;check for no pointer to parameter we built 00406B18 740F | +--jz L00406B29 00406B1A 8B4D10 | | mov ecx,[ebp+10h] 00406B1D C60100 | | mov byte ptr [ecx],00h ;terminate parameter we are building 00406B20 8B5510 | | mov edx,[ebp+10h] 00406B23 83C201 | | add edx,00000001h 00406B26 895510 | v mov [ebp+10h],edx 00406B29 | L00406B29: 00406B29 8B4518 | mov eax,[ebp+18h] ;number of parameters. argc 00406B2C 8B08 | mov ecx,[eax] 00406B2E 83C101 | add ecx,00000001h ;increment argc (number of parameters) 00406B31 8B5518 | mov edx,[ebp+18h] ;number of parameters argc 00406B34 890A | mov [edx],ecx 00406B36 E9E8FDFFFF +<---------------------jmp L00406923 00406B3B L00406B3B: ;end parsing parameters off command line 00406B3B 837D0C00 cmp dword ptr [ebp+0Ch],00000000h 00406B3F 7412 +--jz L00406B53 00406B41 8B450C | mov eax,[ebp+0Ch] 00406B44 C70000000000 | mov dword ptr [eax],00000000h ;terminate argv[] vector 00406B4A 8B4D0C | mov ecx,[ebp+0Ch] 00406B4D 83C104 | add ecx,00000004h 00406B50 894D0C v mov [ebp+0Ch],ecx 00406B53 L00406B53: 00406B53 8B5514 mov edx,[ebp+14h] ;pointer to argc count 00406B56 8B02 mov eax,[edx] 00406B58 83C001 add eax,00000001h ;increment argc count (+1 for program filename) 00406B5B 8B4D14 mov ecx,[ebp+14h] 00406B5E 8901 mov [ecx],eax 00406B60 8BE5 mov esp,ebp 00406B62 5D pop ebp 00406B63 C3 retn ;----------------------------------------------------------------------------------------------------