flat assembler
Message board for the users of flat assembler.
Index
> Windows > Get command line args on Windows |
| Author |
|
|
revolution 15 Feb 2022, 14:36
Code: invoke GetCommandLineA
invoke GetCommandLineW
;or
invoke GetCommandLine |
|||
|
|
macomics 15 Feb 2022, 19:38
+ CommandLineToArgvW
|
|||
|
|
FlierMate 16 Feb 2022, 05:04
There is an example "Command line parameters" (Handling the command line parameters in Windows)
https://flatassembler.net/examples.php |
|||
|
|
Walter 16 Feb 2022, 17:22
Not anything better than those already mentioned but just an example of an additional way to do it.
Code: ;************ ;* Args.asm * ;************ format PE CONSOLE entry start include 'win32ax.inc' section '.text' code readable executable start: cinvoke __getmainargs,argc,argv,env,0,NULL cinvoke printf,<"Argc count is %d",13,10>,[argc] mov eax,[argv] cinvoke printf,<"Program name is %s",13,10>,dword [eax] mov ebx,1 .while ebx < [argc] add [argv],4 mov eax,[argv] cinvoke printf,<"argv[%d] = %s",13,10>,ebx,dword [eax] inc ebx .endw invoke ExitProcess,0 section '.data' data readable writeable argc dd ? argv dd ? env dd ? section '.idata' import data readable writeable library kernel32,'kernel32.dll',\ msvcrt,'msvcrt.dll' import kernel32,\ ExitProcess,'ExitProcess' import msvcrt,\ __getmainargs,'__getmainargs',\ printf,'printf' ![]() |
|||
|
|
Tomasz Grysztar 16 Feb 2022, 19:35
OK, then we are missing an example using CommandLineToArgvW, so let me try:
Code: format PE GUI 4.0 include 'win32w.inc' ID_DIALOG = 100 ID_LIST = 101 section '.text' code readable executable entry $ invoke GetModuleHandle,0 invoke DialogBoxParam,eax,ID_DIALOG,HWND_DESKTOP,DialogProc,0 invoke ExitProcess,0 proc DialogProc uses ebx esi, hwnd,msg,wparam,lparam locals num dd ? endl push ebx esi edi cmp [msg],WM_INITDIALOG je .wminitdialog cmp [msg],WM_COMMAND je .wmcommand cmp [msg],WM_CLOSE je .close xor eax,eax jmp .finish .wminitdialog: invoke GetDlgItem,[hwnd],ID_LIST mov ebx,eax invoke GetCommandLine lea edx,[num] invoke CommandLineToArgv,eax,edx test eax,eax jz .close mov esi,eax .add: lodsd invoke SendMessage,ebx,LB_ADDSTRING,0,eax dec [num] jnz .add jmp .processed .wmcommand: cmp [wparam],BN_CLICKED shl 16 + IDCANCEL jne .processed .close: invoke EndDialog,[hwnd],0 .processed: mov eax,1 .finish: pop edi esi ebx ret endp section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL',\ shell,'SHELL32.DLL' import kernel,\ GetModuleHandle,'GetModuleHandleW',\ GetCommandLine,'GetCommandLineW',\ ExitProcess,'ExitProcess' import user,\ DialogBoxParam,'DialogBoxParamW',\ GetDlgItem,'GetDlgItem',\ SendMessage,'SendMessageW',\ EndDialog,'EndDialog' import shell,\ CommandLineToArgv,'CommandLineToArgvW' section '.rsrc' resource data readable directory RT_DIALOG,dialogs resource dialogs,\ ID_DIALOG,LANG_ENGLISH+SUBLANG_DEFAULT,main dialog main,'Argv',80,80,220,200,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME dialogitem 'LISTBOX','',ID_LIST,10,10,200,180,WS_VISIBLE+WS_VSCROLL+LBS_DISABLENOSCROLL enddialog |
|||
|
|
Walter 16 Feb 2022, 22:47
Very eloquent example!
That should make for some good choices for the OP. |
|||
|
|
macomics 17 Feb 2022, 10:12
I got alternative algorithms from my library to parse the command line. The main function transfers the text to the stack and clearing the memory can be done by simply loading the saved stack top when exiting the calling function. The archive contains versions for 32 and 64 bit sources, as well as versions of functions for ANSI and Unicode. I also cleaned the code from my macros, so it no longer requires any additional include files.
Code: section 'text' code readable executable entry $ push rbp mov rbp, rsp sub rsp, 32 call [GetCommandLineA] mov rsp, rbp call CmdLine2ArgvA ; return rax = rsp = argv mov r8, rax ; word [rax + 0] = offset argv[0] = argc * 2 ; word [rax + 2] = offset argv[1] ; . . . ; word [rax + 2 * N] = offset argv[argc - 1] ; byte [rax + 2 * N + 2] = copy GetCommandLineA call CmdLineCount ; return rax = argc; call main mov ecx, eax lea rsp, [rbp - 32] call [ExitProcess] main: ; rax = argc, r8 = argv push rbp mov rbp, rsp mov rax, r8 mov edx, 1 call CmdLineIndex ; return rax = argv[1] or CPU_FL_CF mov rax, r8 xor edx, edx call CmdLineRmov ; remove argv[0] . . . xor eax, eax mov rsp, rbp pop rbp retn include 'WinCmdLn\x64.ASM'
|
|||||||||||
|
|
chastitywhiterose 06 Nov 2025, 05:50
Here is my way of handling command line arguments in Windows. It is a command line program that first prints the entire command line from the GetCommandLineA W32 API function. Then it prints the number of bytes of the string. Then it prints each argument on a separate line. It uses the same filter I wrote for my DOS programs to turn spaces into zeroes and then finds the next beginning of a string to loop through them all until the end. It uses my own IO library to display strings to the console so I will attach that to this post too.
Code: format PE console include 'win32ax.inc' include 'chastelibw32.asm' main: mov [radix],10 ; Choose radix for integer output. mov [int_width],1 ;get command line argument string call [GetCommandLineA] mov [arg_start],eax ;back up eax to restore later ;short routine to find the length of the string ;and whether arguments are present mov ebx,eax find_arg_length: cmp [ebx], byte 0 jz found_arg_length inc ebx jmp find_arg_length found_arg_length: ;at this point, ebx has the address of last byte in string which contains a zero ;we will subtract to get and store the length of the string mov [arg_end],ebx sub ebx,eax mov eax,ebx mov [arg_length],eax ;display the arg string to make sure it is working correctly mov eax,[arg_start] call putstring call putline ;print the length in bytes of the arg string mov eax,[arg_length] call putint ;this loop will filter the string, replacing all spaces with zero mov ebx,[arg_start] arg_filter: cmp byte [ebx],' ' ja notspace ; if char is above space, leave it alone mov byte [ebx],0 ;otherwise it counts as a space, change it to a zero notspace: inc ebx cmp ebx,[arg_end] jnz arg_filter arg_filter_end: ;optionally print first arg (name of program) mov eax,[arg_start] call putstring call putline ;this loop is very safe because it only prints arguments if they are valid ;if the end of the args are reached by comparison of eax with [arg_end] ;then it will jump to args_none and proceed from there args_list: call get_next_arg cmp eax,[arg_end] jz args_none call putstring call putline jmp args_list args_none: ;Exit the process with code 0 push 0 call [ExitProcess] .end main arg_start dd 0 ;start of arg string arg_end dd 0 ;address of the end of the arg string arg_length dd 0 ;length of arg string arg_spaces dd 0 ;how many spaces exist in the arg command line ;function to move ahead to the next art ;only works after the filter has been applied to turn all spaces into zeroes get_next_arg: mov ebx,[arg_start] find_zero: cmp byte [ebx],0 jz found_zero inc ebx jmp find_zero ; this char is not zero, go to the next char found_zero: find_non_zero: cmp ebx,[arg_end] jz arg_finish ;if ebx is already at end, nothing left to find cmp byte [ebx],0 jnz arg_finish ;if this char is not zero we have found the next string! inc ebx jmp find_non_zero ;otherwise, keep looking arg_finish: mov [arg_start],ebx ; save this index to variable mov eax,ebx ;but also save it to ax register for use ret ;we can know that there are no more arguments when ;the either [arg_start] or eax are equal to [arg_end]
|
|||||||||||
|
|
Mаt Quasar 06 Nov 2025, 15:34
Need to process command-line argument in quotes too.
|
|||
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.