Скачать работу в формате MO Word.

Разработка командного процессора, реализующего команды dir и mkdir на ассемблере

Министерство образования и науки Республики Беларусь


Белорусский Государственный ниверситет Информатики и Радиоэлектроники


Факультет Компьютерного Проектирования






Пояснительная записка


к курсовому проекту по теме


"Разработка коммандного процессора"





Выполнил

студент гр.410703


Федосенко Д.В.


Руководитель работы


Ширинский В.П.






Минска 1996





Содержание


Введение


1. Анализ технического задания.................................


2. Разработка алгоритма........................................


3. Разработка структуры данных.................................


4. Кодирование алгоритма.......................................


5. Тестирование и отладка программы............................


Заключение .....................................................


Литература .....................................................


Приложение .....................................................



















Введение


Появление микропроцессоров в 60-е годы связано са разработкой ин-

тегральных схем (ИС). Интегральные схемы объединяли в себе различные

электронные компоненты в единый элемент на силиконовом чипе. Разработ-

чики становили этот крошечный чипв стройство, напоминающее сороко-

ножку, и включили его в функциональные системы. В начале 70-ха годов

микрокомпьютеры на процессоре Intel 8008 возвестили о первома поколе-

нии микропроцессоров.

К 1974 г. появилось второе поколение микропроцессоров общего наз-

начения Intel 8080. Данный спех побудил другие фирмы к производству

процессоров Intel 8080 или аналогичных.

В 1878 г. фирма Intel выпустил процессора третьего поколения -

Intel 8086, который обеспечивал некоторую совместимость с 8080 и яв-

лялся значительным продвижением вперед в данной области. Для поддер-

жки более простых устройств и обеспечения совместимости c стройства-

ми ввода-вывода того времени Intel разработал разновидность процессо-

ра 8086 - процессор 8088, который в 1981 г. ьыл выбран фирмой IBM для

ее персональных компьютеров.

Более развитыми версиями являются для процессор 8088а процессор

80186, для процессора 8086 - процессоры 80186, 80286, 80386, кото-

рые обеспечили дополнительные возможности и повысили мощность вычисле-

ний.

Распространение микропроцессоров послужило причиной пересмотра от-

ношения к языку Фсскмблер по двум основным причинам. Во-первых, прог-

раммы, написанные на языке Ассемблер, требуют знаительно меньше обье-

ма памяти и времени выполнения. Во-вторых, знание языка Ассемблера и

результирующего машинного кода дыет понимание архитектуры машины, что

врядли обеспечивается при работе н языкаха высокого уровня. Хотя

большинство специалистов в области программного обеспечения ведут раз-

работки на языках высокого ровня, таких, как Паскаль или СИ, что про-

ще при написании программ, но наиболее мощное и эффективное програм-

мное обеспечение полностью или частично написано на языке Ассемблер.












1. Анализ технического задания


В данном курсовом проекте необходимо разработать программу на язы-

ке Ассемблер для МП Intel 8086 реализующую функции командного процес-

сора DIR и MKDIR. Т.е. наша программа должна создавать подкаталога c

указанием диска и маршрут (функция MKDIR) иа выводить, казанный

пользоватем каталог. Вовремя создания подкаталога вносятся изменения в

таблицу размещения файлов (FAT), с тем чтобы сектора, используемые

этим подкаталогам были доступны другим файлам.

Для роботы с дисковой памятью в расширенной версии DOS нам понадо-

бятся операции, которые включают использование строк в формате ASCIIZ

для начальной установки дисковода, пути доступа и имени файла;а файло-

вого номера для доступу к файлу; специальных кодов возврата.

Для создания подкаталога методома дескриптор файл используется

функция 39H прерывания 21H. В DS:DX заносится строка ASCIIZ, содержа-

щей идентификацию файла (все параметры необязательные), строка должна

завершаться 00H, например:

PATHNAMEа DBа 'C:\UTIL\NU.EXE',0

Обратная косая (или прямая косая) используется в качестве разделителя.

Hулевой байт (zero) завершает строку (отсюда название ASCIIZ).

При спешной операции создания подкаталога, флаг CF станавливает-

ся в 0. При неуспешной операции флаг CF устанавливается в 1, в ре-

гистр AX помещается код ошибки, зависящий от операции (таблица 1.1), в

нашем случае, если не найден казанный диск или путь, то в AX возвра-

щается код ошибки 03. В имени создаваемого подкаталога не могута быть

использованы следующие символы:

" : ; / \ | ? * + = [ ]., < >


Таблица 1.1

┌────┬──────────────────────────────────────┐

│ Nа │ Описание ошибки │

├────┼──────────────────────────────────────┤

│ 01 │ Ошибка номера функции │

│ 02 │ Файл не найден │

│ 03 │ Путь доступа не найден │

│ 04 │ Открыто слишком много файлов │

│ 05 │ Доступ не разрешен │

│ 06 │ Ошибка файлового номер │

│ 07 │ Блок правления памятью разрушен │

│ 08 │ Hедостаточно памяти │

│ 09 │ Ошибка адреса блока памяти │

│ 10 │ Ошибка оборудования │

│ 11 │ Ошибка формат │

│ 12 │ Ошибка кода доступ │

│ 13 │ Ошибка данных │

│ 15 │ Ошибка дисковод │

│ 16 │ Попытка далить оглавление │

│ 17 │ Hе то устройтво │

│ 18 │ Hет больше файлов │

└────┴──────────────────────────────────────┘



Для организации работы, нам понадобится знание структуры записи

файла каталогов, которая приведена в таблице 1.2.


Таблица 1.2

┌───┬──────────┬───────┬───────────────────────────┐

│ N │ Смещение │ Длина Значение поля │

(байт)а │ (байт)│ │

├───┼──────────┼───────┼───────────────────────────┤

│1а │ 0а а 8 │ Имя файл │

├───┼──────────┼───────┼───────────────────────────┤

│2а │ 8 3 │ Расширение имени файл │

├───┼──────────┼───────┼───────────────────────────┤

│3а │ 11 1 │ Байт атрибутов файлов │

├───┼──────────┼───────┼───────────────────────────┤

│4а │ 12 10а │ Зарезервировано для DOS │

├───┼──────────┼───────┼───────────────────────────┤

│5а │ 22 2 │ Время │

├───┼──────────┼───────┼───────────────────────────┤

│6а │ 24 2 │ Дат │

├───┼──────────┼───────┼───────────────────────────┤

│7а │ 26 2 │ Стартовый номер кластер │

├───┼──────────┼───────┼───────────────────────────┤

│8а │ 28 4 │ Размер файл │

└───┴──────────┴───────┴───────────────────────────┘


Вторая функция курсового проекта (команда DIR), будет реализова-

на с помощью 21-го прерывания. Функции 21-го прерывания, которые мы

будем использовать, рассмотрены в 4 главе.


2. Разработка алгоритма


Разработаем алгоритм для разрабатываемой программы. Данные в прог-

рамму будем передавать в командной строке. Далее будема анализировать

командную строку следующим образом:

1. Если командная строка пуста, то выводим подсказку;

2. Если встречается первым ключ /D - то выводим текущий директорий;

3. Если встречается первым ключ /M -а информируема пользователя о

том, что он забыл указать имя поддиректория, для его создания;

4. После этого записываем все до первого пробела в строку PATH -

это будет маска файлов.

5. Анализируя далее, смотрим, если стоит /D - то выводим директо-

рий по маске, если стоит /M - то создаем подкаталог по маске.

Блок схема алгоритма приведена в приложении.


3. Разработка структуры данных


В курсовом проекте задействовано множество переменных:


┌─────────┬────────────────────────────────────────────────────────────┐

│Hазвание │ Содержание переменной │

├─────────┼────────────────────────────────────────────────────────────┤

│ HelpStr │ Текст подсказки │

│ stringT │ К байт всего на данном диске │

│ stringF │ К байт свободно на диске │

│ stringU │ Вывод содержимого каталог │

│ err_m1а │ Ошибка номера функции! │

│ err_m2а │ Файл не найден! │

│ err_m3а │ Путь доступа не найден! а│

│ err_m4а │ Открыто слишком много файлов! │

│ ok_make │ Подкаталог создан! │

│ no_make │ Подкаталог не создан, т.к. вы не казали его имя! │

│ │ Для вывода подсказке запустите программу без параметров. │

│ str_f │ Вы не казали ключ! │

│ str_k │ Вы казали неверный ключ! │

│ totalKB │ Ячейка для хранения объема диск │

│ freeKBа │ Ячейка для хранения размера свободного мест │

│ temp │ Рабочая переменная │

│ path │ Текущий каталог (пока не определен - пустой) │

│ NewDTAа │ Описываем структуру DTA │

│ AttrF │ Атрибут файл │

│ TimeF │ Время создания файл │

│ DateF │ Дата создания файл │

│ SizeF │ Размер файл │

│ NameF │ Имя файла вместе с расширением │

└─────────┴────────────────────────────────────────────────────────────┘


Процедуры, входящие в курсовой проект:

┌─────────────────────────────────────────────────────────────────────────┐

│ Процедура высчитывает и выводит время создания файла/каталог │

│ WrtTime │

├─────────────────────────────────────────────────────────────────────────┤

│ Процедура высчитывает и выводит дату создания файла/каталог │

│ WrtDate │

├─────────────────────────────────────────────────────────────────────────┤

│ Забивает пробелами поле, в которое записывается имя файла (NameF) │

│ Это необходимо для того, чтобы не было наложений имен файлов при выводе │

│ ClrName │

├─────────────────────────────────────────────────────────────────────────┤

│ Выводит имя каталога на экран │

│ WrtDir │

├─────────────────────────────────────────────────────────────────────────┤

│ Выводит имя файла на экран │

│ WrtFile │

├─────────────────────────────────────────────────────────────────────────┤

│ Выводит метку текущего диск │

│ WLabel │

├─────────────────────────────────────────────────────────────────────────┤

│ Производит перевод строки и возврат каретки │

│ crlf │

├─────────────────────────────────────────────────────────────────────────┤

│ Выводит на экран текущий каталог │

│ curdir │

├─────────────────────────────────────────────────────────────────────────┤

│ Получает информацию о диске. Номер диска берет из строки поиск │

│ После вызова в AX - количество секторов в кластере │

│ в BX - число свободных кластеров │

│ в CX - число байтов в секторе │

│ в DX - число кластеров на диске │

│ GetInfo │

│ │

├─────────────────────────────────────────────────────────────────────────┤

│ Выводит размер текущего диска в Килобайтах │

│ totsize │

├─────────────────────────────────────────────────────────────────────────┤

│ Выводит размер свободного пространств │

│ текущего диска в Килобайтах │

│ fresize │

├─────────────────────────────────────────────────────────────────────────┤

│ Процедура вывода числа в десятичном формате │

│ Decimal │

└─────────────────────────────────────────────────────────────────────────┘


4. Кодирование алгоритма


Запишем разработанный нами алгоритм в мнемокоде на языке Ассемблер.

Далее более подробно опишем основные прерывания, которые будем ис-

пользовать.

Основным прерыванием, используемым в программе, является прерыва-

ния INT 21H (DOS Functions). Используемые функцииа этого прерывания

следующие:

Параметры Описание


Входные: AH 02H - Вывод на дисплей

DL символ для посылки на стандартное стройство

Выходные: нет

───────────────────────────────────────────────────────────────────────────

Входные: AH 09H - Вывод строки на дисплей

DS:DX Адрес строки, заканчивающаяся знаком '$' (ASCII 24H)

Выходные: нет

───────────────────────────────────────────────────────────────────────────

Входные: AH 1aH - становка адреса DTA.

DS:DX адресс DTA области

Выходные: нет

───────────────────────────────────────────────────────────────────────────

Входные:а AH 19H - Получить информацию о текущем диске

Выходные: AL DOS current default drive number (0=A, 1=B, и т.д.)

───────────────────────────────────────────────────────────────────────────

Входные:а AH 36H - Получить информацию о свободном месте на диске

DL drive number (0=default, 1=A, и т.д.)

Выходные: AX H если DL было invalid drive number

иначе количество секторов верно

BX количество свободных секторов (allocation units)

CX байт на сектор (обычно 512)

DX общее количество секторов на диске

Доп.информация: Выходная информация обычно подсчитывается как

общий размер диска и количество свободного места на диске:


Если AX = H, то вы не правильно указали диск.


Иначе, свободного места в байтах = (AX * CX * BX)

общий размер в байтаха = (AX * CX * DX)


Если сектора по 512 байт, более просто подсчитывать КБ:

свободного места в Ба = (AX * BX) / 2

общий размер в КБ = (AX * DX) / 2

───────────────────────────────────────────────────────────────────────────

Входные: AH 3fH - Создать подкаталог

Функция описывалась нами ранее.

───────────────────────────────────────────────────────────────────────────

Входные: AH 47H - Информация о текущем директории

DL drive number (0=default, 1=A, etc.)

DS:SI address of a local buffer to hold a pathname (64 bytes)

Выходные: AX передается ошибка (Таблица 1.1)

───────────────────────────────────────────────────────────────────────────

Входные: AH 4fH - Hайти следующий совпадающий файл

DS:DX адресс данных с предыдущего 4eH поиска файла

───────────────────────────────────────────────────────────────────────────

Входные: AH 4eH - Hвайти первый совпадающий файл

DS:DX строка пути к файлу ASCIIZ

CX атрибут файлы для поиска

───────────────────────────────────────────────────────────────────────────

Кроме 21h прерывания мы использовали функцию 0eH прерывания INT 10H:


Данная функция обеспечивает вывод символа на монитор в режиме те-

летайпа. Для выполнения этой функции в AL помещают выводимый символ, в

BL цвет текста и номер строницы в BH. Hапример, символы: CR (0dH), LF

(0aH), звуковой сигнал (07H) и т.д. Данная функция автоматически кур-

сор, переводит символы на следующую строку, выполняет прокрутку экра-

на и сохраняет текущие атрибуты экрана.

Также мы использовали прерывание INT 20H для выхода в DOS. Оно не

имеет параметров.

Полный текст программы приведен в Приложении.


5. Тестирование и отладка программы


D:\ASM>kp.comа <ВВОД>


KP v1.0, Copyright (c) 1997, БГУИР, Федосенко Д.В.


При запуске без параметров выводит подказку

Запуск с параметром должен иметь вид:а kp диск:\каталог\маска [/D] [/M]

Где маска (при использовании /D) - любые символы и имена, включая * и ?

(при использовании /M) - название подкаталога.

/D - вывод директория по маске /M - создание подкаталога по маске

Например:kp C:\LANG\BP\*.* /D - вывод всех файлов и каталогов из C:\LANG\BP

kp C:\*а /D - вывод только каталогов из корневого каталога диска C:

kp C:\UTIL /M - создание подкаталога UTIL в корневом диска С:

kp /D - вывод всех файлов и каталогов по текущему пути

Если ВЫ используете /M, то казывать название подкаталога обязательно!


D:\ASM>kp c:\cd\*.* /Dа <ВВОД>


Вывод содержимого каталога c:\cd\*.*

Метка диска DIMKA


. <КАТАЛОГ> 29/01/97 18:18:44

.. <КАТАЛОГ> 29/01/97 18:18:44

read_me.txt 1834 19/11/96 17:58:40

rcdsim.com 6604 13/09/95а а03:00:00

loadcd.exe 0352 13/09/95 03:00:00

rcdpc.sys 4231 13/09/95 03:00:00

run_me.bat 40 06/02/97 13:54:38


30724К байт всего на данном диске

616К байт свободно на диске


D:\ASM>kp c:\cd\util /Mа <ВВОД>


c:\cd\util

Подкаталог создан!


D:\ASM>kp c:\cd\*.* /D


Вывод содержимого каталога c:\cd\*.*

Метка диска DIMKA


. <КАТАЛОГ> 29/01/97 18:18:44

.. <КАТАЛОГ> 29/01/97 18:18:44

UTIL <КАТАЛОГ> 10/04/97 19:57:48

read_me.txt 1834 19/11/96 17:58:40

rcdsim.com 6604 13/09/95 03:00:00

loadcd.exe 0352 13/09/95 03:00:00

rcdpc.sys 4231 13/09/95 03:00:00

run_me.bat 40 06/02/97 13:54:38


30724К байт всего на данном диске

615К байт свободно на диске


D:\ASM>kp * /D <ВВОД>


Вывод содержимого каталога *

Метка диска NPACD


. <КАТАЛОГ> 19/02/97 19:20:34

.. <КАТАЛОГ> 19/02/97 19:20:34

THELP6<КАТАЛОГ> 07/04/97 22:08:48


48355К байт всего на данном диске

892К байт свободно на диске


В процессе тестирования были замечены проблемы с выводома информа-

ции при работе в системе WINDOWS95 (v4.0095). Автор надеется, что с

выходом системы WINDOWS98 проблем не будет.


Заключение


В процессе выполнения курсового проекта я более широко изучил фун-

кции прерываний DOS и BIOS. Hаучился применять их на практике, а так-

же ознакомился со структурой построения программы, реализующей фун-

кйии коммандного процессора. Hаучился пользоваться справочной и дру-

гой литературой.




Литература


1. Бек Л. Введение в системной программирование


2. Соловьев Г.H. Операционная система ЭВМ, Высшая школа, 1989г


3. Краковяк С. Основы организации и функционирования операционной

системы ЭВМ


4. Вишняков В.А., Петровский А.А. Системное обеспечение микроЭВМ


5. Hортон П. Персональный компьютер фирмы IBM и операционная система

MS-DOS


6. Финогенов К.Г. Самоучитель по системным функциям MS-DOS


7. Абель П. Язык ассемблер для IBM PC и программирования, Высшая шко-

ла, 1992г



Приложение


;----------------------------------------

;а Курсовой проект по дисциплине

; "Системное программное обеспечение"

;а студента гр.410703 Федосенко Д.В.

; (c)1997 БГУИР

;----------------------------------------

.MODEL TINY

.CODE

ORG 100h

begin:а jmp start


HelpStr db 13,10,'KP v1.0, Copyright (c) 1997, БГУИР, Федосенко Д.В.'

db 13,10,13,10,'При запуске без параметров выводит подказку'

db 13,10,'Запуск с параметром должен иметь вид:а kp диск:

\каталог\маска [/D] [/M]'

db 13,10,'Где маска (при использовании /D) - любые символы и

имена, включая * и ?'

db 13,10,' (при использовании /M) - название

подкаталога.'

db 13,10,'/D - вывод директория по маске

/M - создание подкаталога по маске'

dbа 13,10,'Например:kp C:\LANG\BP\*.* /D - вывод всех файлов

и каталогов из C:\LANG\BP'

db 13,10,' kp C:\*а /D - вывод только каталогов из

корневого каталога диска C:'

db 13,10,' kp C:\UTIL /M - создание подкаталога UTIL

в корневом каталоге диска С:'

db 13,10,' kp /D - вывод всех файлов и каталогов по

текущему пути'

db 13,10,'Если ВЫ используете /M, то казывать название

подкаталога обязательно!',13,10,'$'

stringT db 'К байт всего на данном диске',13,10,'$'

stringF db 'К байт свободно на диске',13,10,'$'

stringU db 13,10,'Вывод содержимого каталога $'

err_m1а db 13,10,'Ошибка номера функции! $'

err_m2а db 13,10,'Файл не найден! $'

err_m3а db 13,10,'Путь доступа не найден! $'

err_m4а db 13,10,'Открыто слишком много файлов! $'

ok_make db 13,10,'Подкаталог создан! $'

no_make db 13,10,'Подкаталог не создан, т.к. вы не указали его имя!'

db 13,10,'Для вывода подсказке запустите программу без

параметров.',10,13,'$'

str_f db 13,10,'Вы не казали ключ! $'

str_k db 13,10,'Вы казали неверный ключ! $'

totalKB dd 0 ; Ячейка для хранения объема диска

freeKBа dd 0 ; Ячейка для хранения размера свободного места

space db ' $' ; Строка разделения

temp dw 0 ; Рабочая переменная


path db 65 dup (0) ; Текущий каталог (пока не определен - пустой)


NewDTAа db 21 dup (0) ; Описываем структуру DTA

AttrF db 0 ; Атрибут файла

TimeF dw 0 ; Время создания файла

DateF dw 0 ; Дата создания файла

SizeF dd 0 ; Размер файла

NameF db 13 dup (0) ; Имя файла вместе с расширением


start:

push cs ; Заносим во все регистры сегмент кода

pop ds ;

push cs ;

pop es ;


;Проверяем строку параметров


mov cl,ds:[80h] ; Число символов параметров

cmp cl,0 ; Не равно-ли число параметров нулю ?

je help ; Если параметров нет, переходим

cmp cl,1 ; Если один параметр, например файл запущен

je help ; по Ctrl-Enter в NC, то тоже выходим


mov al,ds:[82h] ; Проверяем на ввод без маски

cmp al,'/' ; Наклонная черта ?

jne not_help ; Нет - выходим

mov al,ds:[83h] ; Да - смотрим дальше

cmp al,'M' ; Если введено /M

je not_m

cmp al,'D' ; Если введно /D

je noparam

jmp not_help

help:

mov ah,9 ; Вывод подсказки

lea dx,HelpStr

int 21h

ret ; Выход в DOS

not_m:

mov ah,9 ; Подкаталог не созданб т.к. вы не

lea dx,no_make ; казали имя

int 21h

ret ; Выход в DOS

not_help: ; Если маска введена

mov ch,0

mov di,81h ; Адрес первого символа параметра

mov al,' ' ; Сканировать будем до первого пробела

CheckParam:

repe scasb ; Запускаем сканирование строки

jne IsParam

IsParam: ; Если пробел найден

mov si,di ; Запоминаем адрес

dec si ; меньшаем на единицу

lea di,path ; станавливаем адрес строки параметров

inc cl

MoveParam:

lodsb ; Загружаем один символ строки параметров

cmp al,' ' а; Проверяем, не равен ли он пробелу

je EndMoveParam ; Если равен, значит конец строки

stosb ; Иначе пересылаем в строку параметров - path

loop MoveParam ; Цикл до конца строки


EndMoveParam:

push ax ;сохраним на всякий случай

lodsb ;загружаем еще один символ

cmp al,'/' ;если это /

je okk

mov ah,9 ;иначе вываливаемся с error

lea dx,str_F

int 21h

int 20h


okk: lodsb ;загружаем еще один символ

cmp al,'D' ;если это /D

je Dire ;то запуск DirE

cmp al,'M' ;если это /M

je MakeE ;то запускаем MakeE

mov ah,9 ;иначе вываливаемся с error

lea dx,str_K

int 21h

int 20h


DirE: pop ax

mov al,0 ; Добавляем символ NUL к строке параметров

mov [di],al


mov ah,9 ; Функция вывода строки

lea dx,stringU ; В DX - адрес строки

int 21h ; Выводим строку "Текущий каталог"


mov ah,40h ; Выводим маску поиска

mov bx,01

mov cx,50

lea dx,path

int 21h


call crlf ; Перевод строки, возврат каретки

jmp skip_curdir ; Обходим определение текущего каталога


NoParam: ; Если не заданы параметры

call curdir ; Определяем текущий каталог

skip_curdir:

lea dx,NewDTA ; станавливаем указатель на свою область DTA

mov ah,1Ah

int 21h


call WLabel ; Выводим метку диска


mov ah,4eh ; Функция находит первый каталог с маской *.*

mov cx,10h ; В CX - атрибут каталога - 10h

lea dx,path ; В DX - путь для поиска (был определен выше)

int 21h

jc NowFiles ; Если ни одного каталога нет, ищем файлы


call WrtDir ; Выводим имя первого найденного каталога

FindNextDir:

mov ah,4fh ; Функция продолжает поиск, начатый ф-цией 4eh

int 21h

jc NowFiles ; Если больше каталогов нет, ищем файлы


call WrtDir ; Выводим найденный каталог

jmp FindNextDir ; Переходим на поиск следующего


NowFiles:

mov ah,4eh ; Функция находит первый файл с маской *.*

mov cx,27h ; В CX - атрибут файла - 27h (RO+Hid+Sys+Arc)

lea dx,path ; В DX - путь для поиска файлов

int 21h

jc halt ; Если файлов нет, то на выход


call WrtFile ; Если файл найден, выводим его имя


FindNextFile:

mov ah,4fh ; Функция продолжает поиск файлов

int 21h

jc halt ; Если больше файлов нет, то на выход


call WrtFile ; Выводим имя файла на экран

jmp FindNextFile ; Переход на поиск следующего файла


halt: call crlf ; Перевод строки, возврат каретки

call totsize ; Вывод объема диска

call fresize ; Вывод оставшегося места

ret ; Выход в DOS

;------------- создание подкаталога ---------------------------------

MakeE:а pop ax ; восстанавливаем ax

mov al,0 ; Добавляем символ NUL к строке параметров

mov [di],al

mov ah,40h ; Выводим маску поиска

mov bx,01

mov cx,50

lea dx,path

int 21h

mov ah,39h ; функция создания подкаталога

lea dx,path

int 21h ; выполнить

cmp ax,01h ; проверка на ошибку #1

je p_err1

cmp ax,02h ; проверка на ошибку #2

je p_err2

cmp ax,03h ; проверка на ошибку #3

je p_err3

cmp ax,04h ; проверка на ошибку #4

je p_err4

mov ah,9h ; Ошибки нет!

lea dx,ok_make ; Вывод строки - Подкаталог создан

int 21h

int 20h ; Выход в DOS

;-------- Обработка ошибок --------------------------------

p_err1: mov ah,9h

lea dx,err_m1

int 21h

int 20h

p_err2: mov ah,9h

lea dx,err_m2

int 21h

int 20h

p_err3: mov ah,9h

lea dx,err_m3

int 21h

int 20h

p_err4: mov ah,9h

lea dx,err_m4

int 21h

int 20h ; Выход в DOS


;------------------------------------------------------------------------


;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

;:: Процедура высчитывает и выводит время создания файла/каталога :::

;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

WrtTime proc near

mov ah,9

lea dx,space

int 21h

mov ax,TimeF

shr ax,11

call DecWrt

mov ax,0e3ah

int 10h

mov ax,TimeF

shl ax,5

shr ax,10

call DecWrt

mov ax,0e3ah

int 10h

mov ax,TimeF

shl ax,11

shr ax,10

call DecWrt

ret

WrtTime endp


;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

;::: Процедура высчитывает и выводит дату создания файла/каталога :::

;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

WrtDate proc near

mov ah,9

lea dx,space

int 21h

mov ax,DateF

shl ax,11

shr ax,11

call DecWrt

mov ax,0e2fh

int 10h

mov ax,DateF

shl ax,7

shr ax,12

call DecWrt

mov ax,0e2fh

int 10h

mov ax,DateF

shr ax,9

add ax,80

call DecWrt

ret

WrtDate endp


;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

; Забивает пробелами поле, в которое записывается имя файла (NameF) ::

; Это необходимо для того, чтобы не было наложений имен файлов при выводе ::

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

ClrName proc near

lea si,NameF ; Получаем адрес имени файла

mov cx,1

rp: cmp cx,13 ; Если CX=13, то имя обработано полностью

je vihod ; поэтому выходим

mov al,0 ; Заносим код символа 0 (пустой символ)

mov [si],al ; Записываем пустой символ в строку NameF

inc si ; величиваем адрес строки

inc cx ; величиваем счетчик записаных символов

jmp rp ; Повторяем цикл

vihod:а ret

ClrName endp


;::::::::::::::::::::::::::::::::::::::

;::: Выводит имя каталога на экран ::::

;::::::::::::::::::::::::::::::::::::::

WrtDirа proc near

cmp AttrF,10h ; Проверяем атрибут: если 10h, то каталог

jne exit1 ; Иначе на выход


mov ah,40h ; Функция вывода строки

mov bx,01

mov cx,12 ; Выводим 13 символов

lea dx,NameF ; В DX - адрес строки вывода

int 21h


mov ah,9

lea dx,dirstr

int 21h


call WrtDate

call WrtTime

call crlf ; Перевод строки, возврат каретки


exit1:а call ClrName ; Чистим поле вывода

ret

dirstrа db '<КАТАЛОГ>$'

WrtDirа endp


;:::::::::::::::::::::::::::::::::::::::

;::: Выводит имя файла на экран ::::::::

;:::::::::::::::::::::::::::::::::::::::

WrtFile proc near

cmp AttrF,10h ; Проверяем атрибут: если не файл, то выходим

je exit2

lea si,NameF ; Загружанм адрес строки в SI

mov cx,1

loop1:

cmp cx,13 ; Проверяем, если CX=13, то вывод закончен

je exit2 ; выходим

mov al,[si] ; Заносим в AL выводимый символ

cmp al,65 ; Сравниваем его с 'A'

jl skip1 ; Если меньше, то не переводим в нижний регистр

cmp al,90 ; Сравниваем AL с 'Z'

jg skip1 ; Если больше, то не переводим в нижний регистр

add al,32 ; Переводим символ в нижний регистр

skip1:

mov dl,al

mov ah,02 ; Функция вывода символа на экран

int 21h

inc si ; величиваем адрес

inc cx ; величиваем сченчик

jmp loop1 ; Переход на следующий символ

exit2:

call ClrName ; Чистим поле вывода


mov ax,word ptr SizeF

mov dx,word ptr SizeF+2

call Decimal


call WrtDate

call WrtTime

call crlf

ret

WrtFile endp


;:::::::::::::::::::::::::::::::::::::::

;::: Выводит метку текущего диска ::::::

;:::::::::::::::::::::::::::::::::::::::

WLabelа proc near

call ClrName ; Чистим поле вывода

mov ah,9 ; Функция вывода строки на экран

lea dx,StringL ; В DX - адрес строки

int 21h


lea si,path4

mov ah,19h ; Получаем текущий диск

int 21h

add al,41h ; Переводим его в букву

mov [si],al ; Заносим во временную строку


lea si,path ; Путь поиска

lea di,path4 ; Временная строка

mov al,[si] ; Берем первый символ пути поиска

cmp al,65 ; Буква диска 'A'?

jl not_xchg ; Если меньше, выходим

cmp al,122 ; Буква диска 'z'?

jg not_xchg ; Если больше, выходим

cmp al,91 ; Если '[' - выход

je not_xchg

cmp al,92 ; Если '\' - выход

je not_xchg

cmp al,93 ; Если ']' - выход

je not_xchg

cmp al,94 ; Если '^' - выход

je not_xchg

cmp al,95 ; Если '_' - выход

je not_xchg

cmp al,96 ; Если '`' - выход

je not_xchg


movа [di],al

not_xchg:

mov ah,4eh ; Ищем файл

mov cx,08h ; с атрибутом 08h, т.е. метку тома

lea dx,path4 ; В DX - путь для поиска

int 21h


mov ah,40h ; Функция вывода строки на экран

mov bx,01

mov cx,13 ; Выводим 13 символов

lea dx,NameF ; В DX - адрес строки

int 21h

call crlf ; Перевод строки, возврат каретки

call crlf ; Перевод строки, возврат каретки

call ClrName ; Чистим поле вывода

ret

StringL db 'Метка диска $'

path4 db 'c:\*.*',0 ; Первый символ будет заменен на текущий диск

WLabelа endp


;::::::::::::::::::::::::::::::::::::::::::::::::::::::

;:::: Производит перевод строки и возврат каретки :::::

;::::::::::::::::::::::::::::::::::::::::::::::::::::::

crlf proc near

mov ax,0e0dh ; Функция вывода символа

int 10h ; Выводим символ 13 на экран

mov ax,0e0ah ; Функция вывода символа

int 10h ; Выводим символ 10 на экран

ret

crlf endp


;::::::::::::::::::::::::::::::::::::::::::

;::: Выводит на экран текущий каталог :::::

;::::::::::::::::::::::::::::::::::::::::::

curdirа proc near

mov ah,9 ; Функция вывода строки

lea dx,stringC ; В DX - адрес строки

int 21h ; Выводим строку "Текущий каталог"


lea si,path

mov ah,19h ; Получаем текущий диск

int 21h

add al,41h ; Переводим его в букву

mov [si],al

inc si

mov al,58 ; Добавляем символ ':'

mov [si],al

inc si

mov al,92 ; Добавляем символ '\'

mov [si],al


mov ah,47h ; Функция получения текущего каталога

mov dl,00

lea si,path+3 ; Добавляем к диску каталог

int 21h


lea si,path ; Производим посимвольный вывод полного пути

a10loop:

cmp byte ptr [si],0

je a20exit

mov al,[si]

mov dl,al

mov ah,02

int 21h

inc si

jmp a10loop

a20exit:

; Добавляем к текущему пути маску *.* для поиска каталогов и файлов

dec si ; меньшаем адрес на 1 и получаем последний

mov al,[si] ; символ, не NUL

inc si ; Возвращаем назад SI

cmp al,92 ; Проверяем, если посл. символ - слэш, то выход

je skip_slash

mov al,92 ; Иначе добавляем символ '\'

mov [si],al

inc si

skip_slash:

mov al,42 ; Добавляем символ '*'

mov [si],al

inc si

mov al,46 ; Добавляем символ '.'

mov а[si],al

inc si

mov al,42 ; Добавляем символ '*'

mov [si],al

inc si

mov al,0 ; Добавляем символ NUL

mov [si],al

call crlf

ret

stringC db 13,10,'Текущий каталог $'

curdirа endp


Div1024 proc near

mov cx,10

dd20: shr ax,1

shr dx,1

jnc dd30

or ah,1b

dd30: loop dd20

ret

Div1024 endp


;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

;:: Получает информацию о диске. Номер диска берет из строки поиска :::

;:: После вызова в AX - количество секторов в кластере :::

;:: в BX - число свободных кластерова :::

;:: в CX - число байтов в секторе :::

;:: в DX - число кластеров на диске :::

;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

GetInfo proc аnear

mov dl,0 ; В DL заносим 0, т.е. текущий диск

lea si,path ; Получаем букву диска из пути поиска

mov al,[si]

sub al,40h ; Переводим ее в цифру


cmp al,0 ; Номер диска 0 ?

jl not_1 ; Если меньше, выходим

cmp al,26 ; Номер диска 26 ?

jg again ; Если больше, то идем на проверку строчных букв

jmp mov_val ; Переход на обработку

again:

sub al,32 ; Если буква диска строчная, меньшаем еще раз

cmp al,0 ; Номер диска 0 ?

jl not_1 ; Если меньше, выходим

cmp al,26 ; Номер диска 26 ?

jg not_1 ; Если больше, выходим

mov_val:

mov dl,al ; Заносим номер диска

not_1:

mov ah,36h ; Функция получения информации о диске

int 21h

ret

GetInfo endp


;::::::::::::::::::::::::::::::::::::::::::::::::::

;:: Выводит размер текущего диска в Килобайтах ::::

;::::::::::::::::::::::::::::::::::::::::::::::::::

totsize proc near

call GetInfo

mov temp,dx ; Запоминаем число кластеров


mul cx ; множаем число секторов на размер сектора

mul temp ; множаем все на количество кластеров


call Div1024 ; Делим на 1024 и получаем размер в Кбайтах

mov word ptr totalKB,ax ; Запоминаем младшее и старшее слово

mov word ptr totalKB+2,dx ; полученного результата


call Decimal


mov ah,9

lea dx,stringT

int 21h

ret

totsize endp


;:::::::::::::::::::::::::::::::::::::::::::::::

;::: Выводит размер свободного пространства ::::

;::: текущего диска в Килобайтах ::::

;:::::::::::::::::::::::::::::::::::::::::::::::

fresize proc near

call GetInfo


mul cx

mul bx


call Div1024

mov word ptr freeKB,ax

mov word ptr freeKB+2,dx


call Decimal


mov ah,9

lea dx,stringF

int 21h

ret

fresize endp


DecWrtа proc near

lea аsi,outst ; очищаем строку

mov cl,0

mov [si],cl

mov [si+1],cl


lea si,outst

mov cl,48

mov [si],cl

mov cx,0010

lea si,outst+1

a20: cmp ax,0010

jb a30

xor dx,dx

div cx

or dl,30h

mov [si],dl

dec si

jmp a20

a30: or al,30h

mov [si],al


mov ah,40h ; выводим строку

mov bx,01

mov cx,02

lea dx,outst

int 21h


ret

outst db 'а '

DecWrtа endp


;:::::::::::::::::::::::::::::::::::::::::::::::::::

;:: Процедура вывода числа в десятичном формате ::::

;:::::::::::::::::::::::::::::::::::::::::::::::::::

Decimal proc C uses es di bx cx dx ds

mov bx,10

push cs

pop es

push ax ; Заполняем массив DecString байтами 00

xor ax,axа ;

cld ;

mov cx,3 ;

lea di,DecStr ;

rep stosw ;

pop ax ;

lea di,DecStr+5 ; DI адресует последний байт массива

std


div bx

push ax

mov ax,dx

or al,30h ; Преобразуем в ASCII-символ.

stosb

pop ax

c10:

xor cx,cx

c20:

cmp ax,bx ; Делимое в AX, делитель в BX.

jb c30 ; Частное накапливается в CX.

sub ax,bx ; Деление методом вычитания

inc cx ; (страхует от переполнения)

jmp c20

c30:

or al,30h ; Переводим в ASCII

stosb ; Заносим в DecString

mov ax,cx

cmp ax,bx

jae c10

or al,0

jz c50

or al,30h

stosb

c50:

mov ah,9

lea dx,space

int 21h


mov ah,9

lea dx,DecStr

int 21h

ret

DecStrа db 6 dup (0)

db '$'

Decimal endp


end begin



РBР[1]F*.FRM*.MAC
<

Б