Подкаталоги во многом подобны корневому каталогу, за исключением того, что они хранятся как обычные файлы, а не в заранее предопределенных секторах. Подкаталоги невозможно спутать с обычными файлами, поскольку объект каталога, относящийся к подкаталогу, имеет специальный байт атрибутов (с установленным битом 5 - см. [5.2.6]). Подкаталоги начинаются с двух специальных 32-байтных объектов, первый из которых имеет имя точка, а второй - две точки. Они ориентируют подкаталог среди окружающих каталогов. Ссылки на подкаталоги нижнего уровня записываются как обычные ссылки на файлы.
Предполагается, что подкаталог может быть прочитан как любой другой файл, поэтому вроде бы не составляет труда загрузить его в память. Но, к сожалению, создатели MS DOS поместили 0 в поле длины файла для элементов, относящихся к подкаталогам. В результате DOS считает, что этот файл имеет нулевую длину и отказывается читать его. Нет простого способа преодолеть эту проблему.
Функции работы через дескрипторы файлов, которые использовались для доступа к корневому каталогу [5.2.1] могут так же просто обращаться к любому подкаталогу. Чтобы вывести все содержимое каталога надо просто использовать функцию 4ЕН для поиска файлов *.*, а затем повторять поиск, используя функцию 4FH. Когда больше не будет файлов, то будет установлен флаг переноса, a AL будет содержать 18. Каждый раз, когда будет обнаружен очередной элемент, в DTA будет записана информация о файле, включая полный его путь (отмечаем использование DTA в функциях, использующих дескриптор файла). Следующий пример выводит полные пути всех обычных файлов подкаталога.
;---в сегменте данных
PATH DB 'A:MAMMALS\*.*',0
DTAH DB 256DUP(?)
;---установка DTA
LEA DX,DTA;DS:DX указывают на DTA
MOV AH,1АН;функция установки DTA
INT 21H;устанавливаем DTA
;---ищем первый файл
MOV AH,4EH;номер функции
LEA DX,PATH;указываем на строку пути
MOV СХ,0;только нормальные атрибуты
INT 21Н;ищем *.*
JC ERROR;обработка ошибок
;---выводим имя файла
NEXT_LINE: LEA BX,DTA;ВХ указывает на DTA
ADD ВХ,30;смещение для имени файла
NEXT_CHAR: MOV DL,[BX];получаем символ из имени
CMP DL,0;проверка на конец строки
JE ENDSTR;уход, если конец
MOV АН,2;иначе, выводим символ
INT 21H;
INC BX;увеличиваем указатель
JMP SHORT NEXT_CHAR;следующий символ
;--- возврат каретки/перевод строки в конце строки
END_STR: MOV АН,2;функция вывода символа
MOV DL,13;код возврата каретки
INT 21H;выводим
MOV DL,10;код перевода строки
INT 21Н;выводим
;---ищем следующий файл
LEA DX,PATH;указываем на строку пути
MOV AH,4FH;номер функции
INT 21Н;ищем следующий файл
JC FINISHED;если нет, то выход
JMP SHORT NEXT_LINE;иначе выводим имя файла
FINISHED:
II. Практическая часть
По условию нам необходимо написать программу, производящую создание, удаление, чтение, изменение каталогов.
В начале нашей программы, мы устанавливаем текущий каталог при помощи функции ЗВН 21-ого прерывания. Для выполнения данной функции нам необходимо указать адрес строки из сегмента данных со значением пути к необходимому каталогу в виде строки ASCII, в конце код 0. Также ставим условие обработки ошибок (если ошибка (CF=1), то в АХ - код ошибки).
Затем, с помощью функции 47Н 21-ого прерывания, читаем полный путь к текущему каталогу. Для входных параметров нам понадобиться в DL указать необходимый дисковод, а также поставим SI указывать на 64 байтовую переменную CURRENT_DIR, которая, собственно, и будет хранить путь к текущему каталогу. Далее эту переменную мы выведем на экран. Следует заметить, что функция возвращает строку без имени накопителя.
Теперь перейдем к созданию подкаталога. Для этого нам понадобиться 39-ая функция 21-ого прерывания. Здесь нам всего лишь необходимо чтобы DX указывал на нашу строку с путем (именем) каталога, в конец пишем код 0.
Далее для демонстрации функции вывода содержимого подкаталога, создадим в созданном нами каталоге 3 файла функцией ЗсН 21-ого прерывания. Затем перейдем к процедуре вывода содержимого подкаталога на экран.
Для начала определим адрес области обмена с диском (DTA) для последующих операций с блоками управления файлами. С помощью функции 1АН 21-ого прерывания установим DTA как область памяти из 256 байт с неопределенным значением.
Чтобы вывести все содержимое каталога на экран, необходимо использовать функцию 4ЕН 21-ого прерывания для поиска файлов *.*, а затем повторять поиск, используя функцию 4FH. Когда больше не будет файлов, то будет установлен флаг переноса, a AL будет содержать 18. Каждый раз, когда будет обнаружен очередной элемент, в DTA будет записана информация о файле, включая полное его имя.
Заключение
В данной курсовой работе была рассмотрена задача создание, удаление, чтение, изменение каталогов. Мы вывели на экран все содержимое каталога, теперь можно его удалить. Для удаления каталога мы сформировали такую же строку пути, которые мы указывали при создании каталога. По функции 3АН 21-ого прерывания наш каталог был удален, заметим, что каталог не будет удален, если он будет содержать какие-либо файлы, поэтому прежде удалили оттуда все файлы и выполнили функцию.
Библиографический список использованной литературы
1. Пирогов В.Ю. Ассемблер. Учебный курс. - 2-е изд., перераб. и доп. СПБ.: БХВ-Петербург, 2003.
2. Журден Р. Справочник программиста на персональном компьютере фирмы IBM PC.
Приложение А. Листинг программы
Title Catalog_Work
stk segment stack
dw 90 dup(?)
stk ends
Data segment
CURRENT_DIR DB 64 DUP(?),'$'
path_cur db 'e:\bp\bin',0,13,10,'$'
path db 'd:\catalog',0
path2 db'd:\catalog\*.*',0
file1 db 'd:\catalog\file 1.txt',0
file2 db 'd:\catalog\file2.txt',0
file3 db 'd:\catalog\file3.txt',0
cat_crt db 'Catalog create> ','$'
wr_msg db 'Napishem informaciuy w catalog',13,10,'Sama informacia: ',13,10;$'
err1_msg db 'Catalog sushestwuiet ili newozmogno sozdat ',13,10,'$'
msgl db 'Pered udaleniem kataloga sotrite iz nego wsiu informaciu i posle nagmite enter', 13,10,'$'
msg_cat_setup db 'Ustanofka tekushego katologa',13,10,'$'
msg_cur_cat db 'Tekushii catalog> ','$'
razd db 13,10,'$'
dta db 256 dup(?)
Data ends
Code segment
assume cs:code, ds:data, ss:stk
begin:
mov ax,data
mov ds,ax
mov ah,9h
lea dx,msg_cat_setup
int 21h
;---Делаем E:\BP\BIN текущем каталогом
MOV AH,3BH;Номер функции
LEA DX,PATH_cur;DS:DX должны указать на путь
INT 21Н;устанавливаем текущий каталог
;---Получаем текущий каталог
MOV АН,47Н;Номер функции
LEA SI,CURRENT_DIR;Указываем на область данных
MOV DL,5;Указываем на диск Е:\
INT 21Н;Помещаем строку по адресу DS:SI
mov ah,9h
lea dx,msg_cur_cat
int 21h
mov ah,9h
lea dx,current_dir
int 21h
;---Создаем новый подкаталог по адресу в PATH
LEA DX,path;Указываем путь и имя подкаталога
MOV АН,39Н;Сама функция
INT 21Н;Создаем
JC ERROR1;Если ошибка то переходим на ошибку
mov ah,9h
lea dx,cat_crt
int 21h
mov ah,9h
lea dx,razd
int 21h
mov ah,9h
lea dx,wr_msg
int 21h
call key
;---Создаем в созданном каталоге 3 файла с расширением.txt
mov ah,3ch
mov al,2
mov cx,0
lea dx,filel
int 21h
mov ah,3ch
mov al,2
mov cx,0
lea dx,file2
int 21h
mov ah,3ch
mov al,2
mov cx,0
lea dx,file3
int 21h
;-------------
jmp a
error 1:
mov ah,9h
lea dx,errl_msg
int 21h
jmp exit
a:
;---Устанавливаем DTA
LEA DX,DTA;DS:DX указывает на DTA
MOV AH,1AH;Функция установки DTA
INT 21H;Устанавливаем DTA
;---Ищем первый файл
MOV AH,4EH;Сама функция
LEA DX,path2;Указываем на строку пути
MOV СХ,0;Только нормальные атрибуты
INT 21Н;Ищем *.*
JC ERROR_rout;Ошибки обрабатываем
;---Выводим имя файла
NEXT_LINE: LEA BX,DTA;ВХ указывает на DTA
ADD ВХ,30;Смещение для имени файла
NEXT_CHAR: MOV DL,[BX];Получаем символ из имени
CMP DL,0;Проверка на конец строки
JE END_STR;Уходим, если конец строке
MOV АН,2;Иначе выводим символ
INT 21Н;
INC ВХ;Увеличиваем указатель
JMP SHORT NEXT_CHAR;следующий символ
;---возврат каретки\перевод строки в конце строки
END_STR: MOV АН,2;Функция вывода символа
MOV DL,13;код возврата каретки
INT 21Н;Выводим
MOV DL,10;код перевода строки
INT 21Н;выводим
;---Ищем следующий файл
LEA DX,path2;Указываем на строку пути
MOV AH,4FH;Номер функции
INT 21Н;Ищем сл. файл
JC FINISHED;Если нет, то выходим
JMP SHORT NEXT_LINE;Иначе выводим имя файла
FINISHED:
mov ah,9h
lea dx,msgl
int 21h
call key
;Удаляем наш подкаталог CATALOG
LEA DX,PATH;DS:DX Путь к подкаталогу
MOV AH,3aH;Функция удаления
INT 21Н;Удаляем
JC ERROR 1;Обработка ошибок
exit:
mov ah,4ch
int21h
error_rout:
jmp exit
;-------------------------------------------
;Процедура, ждет нажатия любой клавиши
;-------------------------------------------
key ргос
xor ah,ah
int 16h
ret
key endp
;-------------------------------------------
code ends
end begin
Приложение Б. Листинг программы
Title Catalog_Work
stk segment stack
dw 90 dup(?)
stk ends
Data segment
CURRENT_DIR DB 64DUP(?),'$'
path_cur db 'e:\bp\bin'A13,10,'$'
path db 'd:\catalog',0
path2 db 'd:\catalog\*.*',0
file 1 db 'd:\catalog\file 1.txt',0
file2 db 'd:\catalog\file2.txt',0
file3 db'd:\catalog\file3.txt',0
cat_crt db 'Catalog create>','$'
wrmsg db ‘Napishem informaciuy w catalog',13,10,'Sama informacia: ',13,10,'$'
errl_msg db 'Catalog sushestwuiet ili newozmogno sozdat ',13,10,'$'
msgl db 'Pered udaleniem kataloga sotrite iz nego wsiu informaciu i posle nagmite enter',13,10,'$'
msg_cat_setup db 'Ustanofka tekushego katologa',13,10,'$'
msg_cur_cat db 'Tekushii catalog> ','$'
razd db 13,10,'$'
dta db 256 dup(?)
Data ends
Code segment
assume cs:сode, ds:data, ss:stk
begin:
mov ax,data
mov ds,ax
mov ah,9h
lea dx,msg_cat_setup
int21h
MOV AH,3BH
LEA DX,PATH_cur
INT 21H
MOV AH,47H
LEA SI,CURRENT_DIR
MOV DL,5
INT 21H
mov ah,9h
lea dx,msg_cur_cat
int 21h
mov ah,9h
lea dx,current_dir
int 21h
LEA DX,path
MOV AH,39H
INT 21H
JC ERROR 1
mov ah,9h
lea dx,cat_crt
int 21h
mov ah,9h
lea dx,razd
int 21h
mov ah,9h
lea dx,wr_msg
int21h
call key
mov ah,3ch
mov al,2
mov cx,0
lea dx,filel
int 21h
mov ah,3ch
mov al,2
mov cx,0
lea dx,file2
int21h
mov ah,3ch
mov al,2
mov cx,0
lea dx,file3
int 21h
jmp a
error 1:
mov ah,9h
lea dx,errl_msg
int 21h
jmp exit
a:
LEA DX,DTA
MOV АН,1АН
INT 21H
MOV AH,4EH
LEA DX,path2
MOV CX,0
INT 21H
JC ERROR_rout
NEXT_LINE: LEA BX,DTA
ADD BX,30
NEXT_CHAR: MOV DL,[BX]
CMP DL,0
JE END_STR
MOV AH,2
INT 21H
INC BX
JMP SHORT NEXT_CHAR
END_STR: MOV AH,2
MOV DL,13
INT 21H
MOV DL,10
INT 21H
LEA DX,path2
MOV AH,4FH
INT 21H
JC FINISHED
JMP SHORT NEXT_LINE
FINISHED:
mov ah,9h
lea dx,msgl
int21h
call key
LEA DX,PATH
MOV AH,
INT 21H
JC ERROR 1
exit:
mov ah,4ch
int 21h
error_rout:
jmp exit
key proc
xor ah,ah
int 16h
ret
key endp
code ends
end begin