Шаг 30.
Параметры командной строки

    На этом шаге мы рассмотрим, как работать с командной строкой.

    Здесь все достаточно просто. Есть API-функция GetCommandLine, которая возвращает указатель на командную строку. Эта функция одинаково работает как для консольных приложений, так и для приложений GUI. Ниже представлена программа, печатающая параметры командной строки. Надеюсь, вы понимаете, что первым параметром является полное имя программы.


    Пример работы с параметрами командной строки.
;Программа вывода параметров командной строки.
.386P
;Плоская модель памяти.
.MODEL FLAT, STDCALL
;Константы.
STD_OUTPUT_HANDLE   equ -11
;Прототипы внешних процедур 
EXTERN GetStdHandle@4:NEAR
EXTERN WriteConsoleA@20:NEAR
EXTERN GetCommandLineA@0:NEAR 
EXTERN ExitProcess@4:NEAR
;Директивы компоновщику для подключения библиотек.
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
;------------------------------------------------
;Сегмент данных.
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
        BUF    DB 100 dup(0)
        LENS   DWORD ?  ;Количество выведенных символов.
        NUM    DWORD  ?
        CNT    DWORD  ?
        HANDL  DWORD  ?
_DATA ENDS 
;Сегмент кода.
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE' 
START: 
;Получить HANDL вывода.
        PUSH STD_OUTPUT_HANDLE
        CALL GetStdHandle@4
        MOV  HANDL,EAX 
;Получить количество параметров.
        CALL NUMPAR 
        MOV  NUM,EAX 
        MOV  CNT,0
;-------------------------------------
;Вьвести параметры командной строки 
LL1:
        MOV  EDI,CNT
        CMP  NUM,EDI
        JE   LL2 
;Номер параметра.
        INC  EDI
        MOV  CNT,EDI 
;Получить параметр с номером EDI.
        LEA  EBX,BUF
        CALL GETPAR 
;Получить длину параметра.
        PUSH OFFSET BUF
        CALL LENSTR 
;В конце - перевод строки.
        MOV  BYTE PTR [BUF+EBX],13
        MOV  BYTE PTR [BUF+EBX+1],10
        MOV  BYTE PTR [BUF+EBX+2],0
        ADD  EBX,2 
;Вывод строки.
        PUSH 0
        PUSH OFFSET LENS
        PUSH EBX
        PUSH OFFSET BUF
        PUSH HANDL
        CALL WriteConsoleA@20
        JMP LL1 
LL2:
        PUSH 0
        CALL ExitProcess@4 
;Процедура определения длины строки.
;Строка -   [EBP+08H].
;Длина в ЕВХ 
LENSTR PROC
      PUSH  EBP
      MOV   EBP,ESP
      PUSH  EAX
;----------------------
      CLD
      MOV   EDI,DWORD PTR  [EBP+08H]
      MOV   EBX,EDI
      MOV   ECX,100 ;Ограничить длину строки.
      XOR   AL,AL
      REPNE SCASB   ;Найти символ 0.
      SUB   EDI,EBX ;Длина строки, включая 0.
      MOV   EBX,EDI
      DEC   EBX
;----------------------
      POP   EAX 
      POP   EBP 
      RET   4
LENSTR ENDP
;Определить количество параметров   (->EAX). 
NUMPAR PROC
      CALL GetCommandLineA@0 
      MOV  ESI,EAX  ;Указатель  на строку.
      XOR  ECX,ECX  ;Счетчик. 
      MOV  EDX, 1   ;Признак. 
L1:
      CMP  BYTE PTR [ESI],0 
      JE   L4
      CMP  BYTE PTR [ESI],32 
      JE   L3
      ADD  ECX,EDX  ;Номер параметра. 
      MOV  EDX,0 
      JMP  L2 
L3:
      OR   EDX,1
L2:
      INC  ESI
      JMP  L1 
L4:
      MOV  EAX,ECX
      RET
NUMPAR ENDP 
;Получить  параметр.
;EBX - указывает на буфер, куда будет помещен параметр.
;В буфер помещается строка с нулем на конце. 
;EDI - номер параметра. 
GETPAR PROC
      CALL GetCommandLineA@0
      MOV  ESI,EAX ;Указатель на строку.
      XOR  ECX,ECX ;Счетчик.
      MOV  EDX,1   ;Признак. 
L1:
      CMP  BYTE PTR [ESI],0
      JE   L4
      CMP  BYTE PTR [ESI],32
      JE   L3
      ADD  ECX,EDX ;Номер параметра.
      MOV  EDX,0
      JMP  L2 
L3:
      OR   EDX,1
L2:
      CMP  ECX,EDI
      JNE  L5
      MOV  AL,BYTE PTR [ESI]
      MOV  BYTE PTR [EBX],AL
      INC  EBX 
L5:
      INC  ESI
      JMP  L1 
L4:
      MOV  BYTE PTR [EBX],0
      RET 
GETPAR ENDP 
_TEXT  ENDS 
       END START
Текст этой программы можно взять здесь.

    Если в командной строке набрать такую команду:

         pr30_1.exe 111 222
то результат работы будет следующим:
  pr30_1.exe
  111
  222

    Рекомендуем самостоятельно разобраться в алгоритме работы процедур NUMPAR и GETPAR.

    Следует отметить, что для трансляции приведенной программы в TASM, кроме обычных, уже известных вам изменений, для совпадающих меток следует в начале имени поставить @@ - признак локальности, а в начале программы поставить директиву LOCALS. Транслятор MASM все метки, стоящие в процедуре, считает локальными.

    Со следующего шага мы начнем рассматривать создание и использование ресурсов.




Предыдущий шаг Содержание Следующий шаг