Аргументы командной строки

Тема в разделе "WASM.BEGINNERS", создана пользователем random, 10 янв 2008.

  1. random

    random New Member

    Публикаций:
    0
    Регистрация:
    10 янв 2008
    Сообщения:
    38
    Написал макрос определения параметров командной строки (цель - получить имена файлов), но чувствую, что до оптимальности ему еще хромать и хромать... Может кто посоветует лучшее решение:
    argv - массив, содержит поочередно адрес начала 1-го; адрес конца 1-го аргумента; адрес начала 2го;...
    argc - число аргументов
    предполагается что аргументы отделены одним или более пробелами, в конце тоже могут быть пробелы
    Код (Text):
    1. _GET_COMMAND_LINE  macro argv,argc      ;CLIstart  DWORD ? / CLIend    DWORD ?
    2. pushad          ;сохраняем регистры
    3. invoke  GetCommandLine
    4. mov     CLIstart,eax    ;начало строки
    5.                         ;#####ищем  конец строки#############
    6. mov     edi, eax        ;начало в edi
    7. xor     al,al           ;ищем NULL
    8. mov     ecx,-1
    9. cld
    10. repne   scasb
    11. not     ecx             ;длина строки
    12. dec     edi             ;scasb проскакивает символ  
    13. mov     CLIend,edi      ;конец строки
    14.                         ;#############поиск аргументов########
    15. mov     edi,CLIstart
    16. xor     edx,edx         ;инициализация счетчика аргументов
    17. xor     esi,esi         ;инициализация индекса массива аргументов
    18.  
    19. start_find:    
    20. mov     argv[esi],edi   ;начало  аргумента
    21. mov     al, 20h         ;ищем первый пробел в серии после аргумента
    22. cld
    23. repne   scasb
    24. mov     ebx,edi
    25. add     esi,4           ;куда пишем адрес конца аргумента
    26. dec     edi             ;scasb проскакивает символ  
    27. mov     argv[esi],edi   ;адрес конца аргумента
    28. inc     edx             ;счетчик аргументов +1
    29. jecxz   out_of_line     ;проверяем, что строка не исчерпана
    30. repe    scasb           ;ищем первый не пробел в серии пробелов
    31. add     esi,4           ;куда пишем адрес начала нового аргумента
    32. dec     edi             ;scasb проскакивает символ
    33. jmp     start_find
    34. out_of_line:
    35. mov     ebx,CLIend
    36. mov     argv[esi],ebx   ;адрес конца аргумента - конец строки
    37. mov     argc,edx         ;возвращаем число аргументов
    38. popad                    ;восстанавливаем регистры
    39.                         ; в результате в argc - число аргументов, в массиве argv- адреса начала и конца аргументов
    40. endm
     
  2. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    Юзай CommandLineToArgvW.
     
  3. random

    random New Member

    Публикаций:
    0
    Регистрация:
    10 янв 2008
    Сообщения:
    38
    Во-первых, такой функции я не нашел в shell32.inc - есть только CommandLineToArgv
    в свою очередь в справке по API нет именно второй. Мож косяк с MASM?
    Во-вторых, как с ней работать, тож непонятно...Может ссылку на пример кода?
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    есть функция в shell32.dll и она одна. называется CommandLineToArgvW.
    имеет прототип:

    LPWSTR * CommandLineToArgvW(
    LPCWSTR lpCmdLine, // pointer to a command-line string
    int *pNumArgs // pointer to a variable that receives the argument count
    );

    Юзать примерно так:

    Код (Text):
    1. argc dd ?
    2. argv dd ?
    3. ...
    4.     invoke GetCommandLineW
    5.     invoke CommandLineToArgvW, eax, offset argc
    6.     mov [argv], eax
     
  5. random

    random New Member

    Публикаций:
    0
    Регистрация:
    10 янв 2008
    Сообщения:
    38
    Все, понял и разобрался,. Единственно, что волнует - например функции GetCommandLineW и GetCommandLine чем-нибудь различаются?
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    нет функции GetCommandLine. так же, как и нету MessageBox, CreateFile, CreateWindow.

    Есть два варианта функций - Ansii (с окончанием A) и Unicode (с окончанием W от wide-char). Соответственно они принимают анси и юникод параметры (если конечно эти функции принимают какие-либ текстовые параметры, иначе есть 1 функция без всяких таких окончаний). В связи с тем что еще после Windows 98 ядро стало функционировать исключительно на юникоде, то W-функции содержат реальный код, а A-функции являются только переходниками к W-функциям.
    Соответственно нет функции GetCommandLine. Есть GetCommandLineA, которую ты, вероятно, и юзал обычно, но есть и GetCommandLineW. Первая получает параметры в анси формате, вторая - в юникоде.

    Но вот CommandLIneToArgvW, так уж сложилась, представлена в одном Unicode-варианте. Поэтому и командную строку ей надо переадвать юникодную.
     
  7. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    ЗЫ.
    Наряду с функциями XxxA и XxxW объявляется в SDK так же макрос Xxx, значение которого зависит от кодировки программы.
    Например, в Си:

    Код (Text):
    1. #ifdef _UNICODE
    2. #define MessageBox MessageBoxW
    3. #else
    4. #define MessageBox MessageBoxA
    5. #endif