На этом шаге мы рассмотрим, как работать с командной строкой.
Здесь все достаточно просто. Есть 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 все метки, стоящие в процедуре, считает локальными.
Со следующего шага мы начнем рассматривать создание и использование ресурсов.