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

Формат:

Дата создания: 10.10.2016

Размер: 11.77 KB

Скачать реферат


         Министерство образования и науки Республики Беларусь Белорусский Государственный Университет Информатики и Радиоэлектроники ______________________________________________________________________                 Факультет Компьютерного Проектирования                         Пояснительная записка                       к курсовому проекту по теме                  "Разработка коммандного процессора"                                                                  Выполнил                                                         студент гр.410703                                                            Федосенко Д.В.                                                       Руководитель работы                                                             Ширинский В.П.                              Минск  1996                                Содержание Введение 1. Анализ технического задания ................................. 2. Разработка алгоритма ........................................ 3. Разработка структуры данных ................................. 4. Кодирование алгоритма ....................................... 5. Тестирование и отладка программы ............................ Заключение ..................................................... Литература ..................................................... Приложение .....................................................                                 Введение     Появление микропроцессоров в 60-е годы связано с  разработкой  ин- тегральных схем (ИС).  Интегральные схемы объединяли в себе  различные электронные компоненты в единый элемент на силиконовом чипе. Разработ- чики установили этот крошечный чипв устройство,  напоминающее  сороко- ножку,  и включили его в функциональные системы.  В начале 70-х  годов микрокомпьютеры на процессоре Intel 8008 возвестили о  первом  поколе- нии микропроцессоров.     К 1974 г. появилось второе поколение микропроцессоров общего  наз- начения Intel 8080. Данный успех побудил другие фирмы  к  производству процессоров Intel 8080 или аналогичных.     В 1878 г. фирма Intel выпустила  процессор  третьего  поколения  - Intel 8086,  который обеспечивал некоторую совместимость с 8080 и  яв- лялся значительным продвижением вперед в данной области.  Для  поддер- жки более простых устройств и обеспечения совместимости с  устройства- ми ввода-вывода того времени 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    ffffH   если DL было invalid drive number                  иначе    количество секторов верно            BX    количество свободных секторов (allocation units)            CX    байт на сектор (обычно 512)            DX    общее количество секторов на диске  Доп.информация: Выходная информация обычно подсчитывается как           общий размер диска и количество свободного места на диске:           Если AX = ffffH, то вы не правильно указали диск.           Иначе,  свободного места в байтах = (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    307240К байт всего на данном диске    6160К байт свободно на диске 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    307240К байт всего на данном диске    6152К байт свободно на диске D:\ASM>kp * /D   <ВВОД> Вывод содержимого каталога * Метка диска NPACD .      <КАТАЛОГ>   19/02/97   19:20:34 ..     <КАТАЛОГ>   19/02/97   19:20:34 THELP6<КАТАЛОГ>   07/04/97   22:08:48    483552К байт всего на данном диске    8928К байт свободно на диске     В процессе тестирования были замечены проблемы с выводом  информа- ции при работе в системе 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,10000000b 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 < Б