Предыдущий раздел | ОПЕРАЦИИ С ФАЙЛАМИ | Следующая глава |
Следующая программа выполняет копирование файла. Имя копируемого файла и имя файла-копии программа запрашивает у пользователя сама.
; Программа копирует файл
; ----------------------------------
; Имя копируемого файла и имя копии вводятся с клавиатуры
;
cr equ 0dh ; Код ASCII возврата каретки
lf equ 0ah ; Код ASCII перевода строки
org 100h
Start: jmp Begin ; Переход через данные
; Данные программы
Msg1 db ‘Введите имя копируемого файла’, cr, lf, ‘$’
Msg2 db ‘Копируемый файл отсутствует’, cr, lf, ‘$’
Msg3 db ‘Введите имя файла-копии’, cr, lf, ‘$’
Msg4 db ‘Ошибка создания файла’, cr, lf, ‘$’
Msg5 db ‘Ошибка чтения файла’, cr, lf, ‘$’
Msg6 db ‘Ошибка записи в файл’, cr, lf, ‘$’
Msg7 db ‘Копирование выполнено’, cr, lf, ‘$’
Lname0 db 81 ; Максимальная длина имени файла
Lname db 0 ; Фактическая длина имени файла
Namefile times 81 db 0 ; Здесь размещается имя файла
Bufer times 512 db 0 ; Буфер для копирования
Lognum1 dw 0 ; Логический номер файла 1
Lognum2 dw 0 ; Логический номер файла 2
; Команды программы
Begin:
; Запрос и открытие копируемого файла
mov dx, Msg3 ; Вывод сообщения с просьбой
mov ah, 9 ; ввести имя
int 21h ; копируемого файла
mov ah, 0ah ; Функция ввода строки
mov dx, Lname0 ; DX ß адрес-смещение буфера ввода
int 21h ; Ввод строки
xor bx, bx ; BX ß 0
mov bl, [Lname] ; BX ß длина имени файла
mov [Namefile+bx], byte 0 ; Запись нулевого байта
mov ah, 3dh ; Открытие
mov dx, Namefile ; копируемого
mov al, 0 ; файла
int 21h ; на чтение
jnc .M1 ; Если успешно
mov dx, Msg2 ; Вывод сообщения
mov ah, 9 ; об отсутствии
int 21h ; копируемого файла
jmp .Exit ; На завершение программы
.M1:
mov [Lognum1], ax ; Сохранение логич. номера файла
;Создание и открытие файла-копии
mov dx, Msg3 ; Вывод сообщения с просьбой
mov ah, 9 ; ввести имя
int 21h ; файла-копии
mov ah, 0ah ; Функция ввода строки
mov dx, Lname0 ; DX ß адрес-смещение буфера ввода
int 21h ; Ввод строки
xor bx, bx ; BX ß 0
mov bl, [Lname] ; BX ß длина имени файла
mov [Namefile+bx], byte 0; Запись нулевого байта
mov ah, 3ch ; Создание
mov dx, Namefile ; и
mov cx, 0 ; открытие
int 21h ; файла-копии
jnc .M2 ; Если успешно
mov dx, Msg4 ; Вывод сообщения
mov ah, 9 ; об ошибке
int 21h ; создания файла
jmp .Exit ; На завершение программы
.M2:
mov [Lognum2], ax ; Сохранение логич. номера файла
; Копирование файла
.M3:
mov ah, 3fh ; Функция чтения из файла
mov bx, [Lognum1] ; BX ß логич. номер читаемого файла
mov cx, 512 ; CX ß число читаемых байтов
mov dx, Bufer ; DX ß адрес-смещение буфера
int 21h ; Чтение из файла в буфер
jnc .M4 ; Если успешно
mov dx, Msg5 ; Вывод сообщения
mov ah, 9 ; об ошибке
int 21h ; чтения файла
jmp .Exit ; На завершение программы
.M4:
mov bx, [Lognum2] ; BX ß логич. номер файла-копии
mov cx, ax ; CX ß число записываемых байтов
mov ah, 40h ; Функция записи в файл
mov dx, Bufer ; DX ß адрес-смещение буфера
int 21h ; Запись из буфера в файл
jnc .M5 ; Если успешно
mov dx, Msg6 ; Вывод сообщения
mov ah, 9 ; об ошибке
int 21h ; записи в файл
jmp .Exit ; На завершение программы
.M5:
cmp ax, 512 ; Конец файла?
jz .M3 ; Если нет
; Завершение программы
mov dx, Msg7 ; Вывод сообщения
mov ah, 9 ; о завершении
int 21h ; копирования
.Exit: mov ax, 4c00h ; Возврат в DOS с
int 21h ; кодом завершения 0
Данная программа сначала запрашивает у пользователя имя копируемого файла, используя для ввода символьной строки с клавиатуры системный вызов DOS – “int 21h” (функция 0Ah) – ввод с клавиатуры символьной строки. При этом в качестве последнего символа строки вводится символ 0Dh (возврат каретки). Этот символ помещается во вводимую строку драйвером клавиатуры при нажатии клавиши <Enter>.
Перед применением вызова программа помещает в регистры DS и DX соответственно адрес-сегмент и адрес-смещение для младшего байта буфера, в который должна быть введена строка. Данный буфер имеет три поля:
1) младший байт содержит максимальное число вводимых символов. Запись этого числа выполняет сама программа перед применением данного вызова;
2) второй байт содержит число фактически введенных символов. Запись в этот байт выполняет DOS;
3) остальные байты буфера содержат введенную строку, заканчивающуюся кодом 0Dh.
Далее программа открывает копируемый файл, если он существует. Иначе соответствующее сообщение выводится на экран пользователю. В случае успешного открытия файла его логический номер, полученный в результате открытия, сохраняется для последующего чтения из файла. Далее создается новый файл, имя которого вводится с клавиатуры. Одновременно этот файл открывается для последующей записи в него.
Собственно копирование выполняется циклически. За одну итерацию цикла одна логическая запись (512 байтов) считывается из исходного файла в буфер программы Bufer, а затем переписывается из него в выходной файл. После этого число фактически записанных байтов сравнивается с числом 512. При неравенстве этих чисел делается вывод о достижении конца файла, и копирование прекращается.
Обратим внимание, что программа не выполняет закрытие файлов. Это объясняется, во-первых, небольшим количеством файлов, открываемых в программе. Во-вторых, вскоре после последней операции записи в файл программа завершается.
Заслуживает внимания оператор:
mov [Namefile+bx], byte 0
Данный оператор выполняет загрузку числа 0, заданного в качестве второго операнда, в ячейку ОП, являющейся первым операндом. Адрес-смещение этой ячейки задан выражением в квадратных скобках и представляет собой сумму адреса-смещения байта, имеющего имя Namefile и содержимого регистра BX. Если бы квадратных скобок не было, то транслятор интерпретировал бы первый операнд не как содержимое ячейки ОП, а как ее адрес.
Для уточнения второго операнда в записанном операторе используется вспомогательный псевдооператор byte (байт). При отсутствии такого вспомогательного оператора транслятор не знает, какова длина пересылаемого данного – байт, слово или двойное слово. Оператор byte или word (слово), или dword (двойное слово) будет лишним, если хотя бы один из операндов есть регистр, так как длина регистра всегда известна транслятору.
Рассмотренная программа пригодна для копирования любых обычных (не каталогов) файлов. Например, она может копировать себя. Допустим, что мы поместили загрузочный модуль программы в файл copir.com, тогда выполнив копирование этого файла в файл с именем, например, copir1.com, получим программу, которая также может выполнять копирование (проверьте это).
Предыдущий раздел | В начало | Следующая глава |