Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы СПО / Мет6.doc
Скачиваний:
28
Добавлен:
12.04.2015
Размер:
406.02 Кб
Скачать

5. Работа с параметрами командной строки

Параметры, которые вводятся после имени программы в командной строке, копируются операционной системой в PSP программы. Сегментный адрес PSP после старта содержится в DS и ES.

По смещению 0080h в PSP находится байт, равный длине строки параметров, сама строка располагаются со смещения 0081h, и оканчивается символом с кодом 0Dh (этот символ не входит в длину строки).

Перед копированием в PSP строка параметров преобразуется в стандартный формат. Она начинается с пробела (20h), между отдельными словами оставляется по одному пробелу, остальные отбрасываются, и отбрасываются пробелы, введенные за последним параметром, таким образом код 0Dh следует сразу за последним словом (рис.1).

Если файл с длинным именем содержит пробелы в имени, то оно передается в командную строку заключенным в кавычки (22h).

Вводится с клавиатуры:

С:>PROG.EXE FILE1.TXT FILE2.TXT ENTER

Содержится в PSP:

[0080h]: 14h (20 символов)

[0081h]: 20h ,“FILE1.TXT”, 20h, FILE2.TXT , 0Dh

Рис.1. Пример передачи параметров в командной строке

6. Пример

Задача: программе в командной строке передаются два имени файла. Скопировать файл_1 под именем файла_2. Имена файлов длинные.

Для функций создания и открытия надо иметь имена файлов в виде ASCIIZ строки. Символ с кодом 0 записывается в конце имени файла прямо в командной строке.

Для ускорения копирования файла чтение и запись производится блоками по 512 байт (один сектор) в цикле. Обычно последний сектор файла занят не полностью, т.е. число прочитанных байт меньше 512. Это является условием окончания цикла копирования.

Текст программы

code segment para

assume cs:code, ds:code, es:code

CmdSize EQU byte ptr ds:[080h]

CmdLine EQU byte ptr ds:[081h]

org 100h

start:

; Анализ параметров командной строки.

cmp CmdSize,0 ; длина строки параметров =0 ?

jne skip1 ; нет - продолжить

run_format_error:

mov ah,9 ; вывести сообщение об ошибке

lea dx,RunFormatErr

int 21h

jmp Exit ; и выйти

skip1:

; Выделение первого имени (cмещение -> в FNameOfs1)

cld

xor cx,cx

mov cl,CmdSize ; в CX длина командной строки

mov FNameOfs1,82h ; по 81h пробел, имя начинается с 82h

; или с 83h, если оно в кавычках

mov di,FNameOfs1

cmp CmdLine[1],'"' ; первый символ имени - кавычки ?

jne no_space_1 ; нет - перейти

inc FNameOfs1 ; пропустить 1-е кавычки

inc di

mov al,'"' ; поиск закрывающих кавычек

repne scasb ; (в CX длина командной строки)

test cx,cx

jz run_format_error ; кавычки не найдены - ошибка

mov byte ptr [di-1],0 ; заменяем кавычки на 0

; di указывает на пробел или 0Dh, если параметр всего 1

no_space_1:

; имя 1-го файла не содержит пробелов.

; ищем символ окончания имени - пробел или 0Dh

cmp byte ptr [di],20h ; сравниваем с пробелом

je first_name_end ; найден конец имени - переход

cmp byte ptr [di],0Dh ; сравниваем с 0Dh

je run_format_error ; равен: всего 1 параметр - ошибка

inc di

dec cx

jmp short no_space_1 ; переходим на следующий символ

first_name_end:

mov byte ptr [di],0 ; заменить пробел на 0

inc di

; Выделение второго имени (cмещение -> в FNameOfs2)

mov FNameOfs2,di

cmp byte ptr [di],'"' ; первый символ имени - кавычки ?

jne no_space_2 ; нет - перейти

inc FNameOfs2 ; пропустить кавычки

inc di

mov al,'"' ; поиск закрывающих кавычек

repne scasb

test cx,cx

jz run_format_error ; кавычки не найдены - ошибка

mov byte ptr [di-1],0 ; делаем имя в ASCIIZ-формате

no_space_2:

; имя 2-го файла не содержит пробелов. Оно должно

; оканчиваться кодом 0Dh.

; Если оканчивается пробелом, то ошибка.

cmp byte ptr [di],0Dh ; сравниваем символ с 0Dh...

je second_name_end

cmp byte ptr [di],20h ; ... и с пробелом

je run_format_error ; равен - ошибка

inc di

jmp short no_space_2 ; переходим на следующий символ

second_name_end:

mov byte ptr [di],0 ; заменяем 0Dh на код 0

; Открываем и создаем файлы

mov ax,716Ch

mov si,FNameOfs1 ; первый файл ...

mov bx,100B ; ... открыть для чтения

mov dx,00001B ; не существует-возвратить ошибку

int 21h

jnc file_is_open ; ошибок нет - перейти

mov ah,9

lea dx,FileNotFound ; вывести сообщение об ошибке

int 21h

jmp exit ; и выйти

file_is_open:

mov Handler1,ax ; сохранить манипулятор

mov ax,716Ch

mov si,FNameOfs2 ; второй файл...

mov dx, 10000B ; ... создать новый

mov bx,001B ; ... и открыть для записи

mov cx,100000B ; атрибут - архивный

int 21h

jnc file_is_created ; ошибок нет - перейти

mov ah,9

lea dx,CantCreateFile ; вывести сообщение об ошибке

int 21h

jmp exit ; и выйти

file_is_created:

mov Handler2,ax ; сохранить манипулятор

; Копируем из первого файла во второй

lea dx,Buffer ; ds:dx - адрес буфера чтения/записи

next:

mov ah,3Fh ; читаем...

mov bx,Handler1 ; ...из первого файла

mov cx,512 ; по 512 байт

int 21h

jc close_files ; ошибка - прекратить копирование

push cx

mov cx,ax ; в AX число прочитанных байт

mov ah,40h ; записываем...

mov bx,Handler2 ; ... во второй файл (число байт в CX)

int 21h

jc close_files ; ошибка - прекратить копирование

pop cx

cmp ax,cx ; число записанных байт = 512 ?

je next ; да (не конец файла) - продолжить

mov ah,9

lea dx,CopyOk ; вывести сообщ.об успешном копировании

int 21h

close_files:

mov ah,3Eh ; закрыть файл 1

mov bx,Handler1

int 21h

mov bx,Handler2 ; закрыть файл 2

int 21h

exit:mov ax,4C00h ; завершить программу

int 21h

;--------- Область данных---------------

RunFormatErr db "ОШИБКА: Heвepный фopmaт зanycka",0Dh,0Ah,"$"

FileNotFound db "ОШИБКА: Файл не найден",0Dh,0Ah,"$"

CantCreateFile db "ОШИБКА: He moгy coздaть файл",0Dh,0Ah,"$"

CopyOk db "Копирование выполнено",0Dh,0Ah,"$"

align word

FNameOfs1 dw ? ; смещение 1-го имени

FNameOfs2 dw ? ; смещение 2-го имени

Handler1 dw ? ; манипулятор для 1-го файла

Handler2 dw ? ; манипулятор для 2-го файла

Buffer db 512 dup (0) ; буфер чтения/записи

code ends

end start

Соседние файлы в папке Лабы СПО