; (ds=PSP)
call NewLine ; перехід на новий рядок
; ------Виведення інформації о програмі
mov di,offset tit1 ; адреса рядка з інформацією о програмі
call StrWrite ; вивід інформації о програмі на консоль
call NewLine ; перехід на новий рядок
; ------Вибір маски
call ParamCount ; отримання в cxчисло параметрів
movdi, offsetdefaultSpec ; встановити diвказівником на
; стандартний шаблон маски
or cx, cx ; перевірка cxна наявність 0
jz @@10 ; якщо cx=0, перехід
xor cx, cx ; обнуління cx(номер параметру)
call GetOneParam ; отримати адресу параметра
; ------Виклик підпрограми обробника
@@10:
movbx, offsetAction ; поміщення в bxадреси процедури Action
callDirEngine ; виклик процедури DirEngineрозгляду
; каталогу
; ------Завершення роботи
Exit:
call NewLine ; перехід на новий рядок
mov ah, 04Ch ; в ahномер функції виходу із програми
moval, [exCode] ; в alкод виходу
int 21h ; виклик DOS, завершення програми
; -------------------------------------------------------------------------------------------
; DirEngine перегляд каталогу
; -------------------------------------------------------------------------------------------
; Вхід cx:bx адреса підпрограми Action
; ds:diадреса ASCII-рядка для пошуку (маска)
; Вихід викликає процедуру Actionпри кожному знаходженні
; файла, що відповідає масці
Регістри ax, cx, dl, di
; -------------------------------------------------------------------------------------------
PROCDirEngine
; ------Виведення заголовку таблиці
pushdi ; збереження diу стеку
movdi,offsettabl ; в diзміщення рядка заголовка таблиці
; ASCII
callStrWrite ; вивід на екран заголовка таблиці
call NewLine
pop di ; відновлення di
; ------Отримання поточного DTA
pushes ; збереження змінюваних регістрів
pushbx
movah, 2Fh ; в ahномер функції DOSотримання DTA
int 21h ; отримати поточний DTA
mov [DTAseg], es ; збереження адреси сегмента DTA
mov [DTAofs], bx ; збереження адреси зміщення DTA
popbx ; відновлення регістрів
popes
; ------Встановлення нового DTAв глобальному 43-байтовому буфері dirData
movdx, offsetdirData ; адреса змінної dirDataпоміщується
; в ds:dx
mov ah, 1Ah ; а ahномер функції DOSвстановлення
; DTA
int 21h ; встановлення нового DTA
; ------Перевірка каталогу на співпадіння імен файлів із маскою в ds:dx
movah, 4Eh ; в ahномер функції DOSпершого
; пошуку
mov cx, 10h ; атрибут файлів і директорій
mov dx, di ; поміщення адреси рядка в ds:dx
jmp short @@20 ; пропуск наступної дії
@@10:
mov ah, 4Fh ; в ahномер функції DOSпродовження
; пошуку
@@20:
int 21h ; пошук першого/наступного входження
jc @@99 ; вихід при помилці, або закінченні
call bx ; виклик процедури Action
jmp @@10 ; повтор дій
@@99:
; ------Відновлення початкової адреси DTA
pushds ; збереження dsу стеку
movds, [DTAseg] ; встановлення старої адреси DTAв ds:dx
movdx, [DTAofs]
movah, 1Ah ; в ahномер функції DOSвстановлення
; DTA
int 21h ; повернення до старої DTA
pop ds ; відновлення ds
ret ; завершення процедури
ENDPDirEngine
; -------------------------------------------------------------------------------------------
; Action виводить дані про файл із буфера dirData
; -------------------------------------------------------------------------------------------
; Вхід dirDataDTAфайла
; Вихід виводить дані про файл (назву, атрибути, дату/час створення,
; розмір)
; Регістри ax, dl, di, cx
; -------------------------------------------------------------------------------------------
PROC Action
push bx ; збереження регістрів
; ------Вивід імені файлу
movdi, offsetdirData+ FileName ; в diзміщення початку імені файлу
callStrWrite ; вивід імені на екран
callStrLength ; отримання в cxдовжини імені
sub cx, 15 ; виявлення на скільки довжина імені
neg cx ; файлу менше поля із 15 символів
mov dl, ' ' ; в dlсимвол пробілу
callWriteSimv ; вивести на екран необхідну, для
; доповнення поля із 15 символів,
; кількість разів
; ------Вивід атрибутів файлу
moval,[offsetdirData+ FileName-9]; в alпоміщується байт атрибуту
mov cx,6 ; в cxкількість значущих бітів у байті
; атрибуту
@@01:
shral,1 ; зсув alвправо,
; в CFпоміщується молодший біт
jb@@02 ; якщо CF=1, то перехід
mov dl, ' ' ; в dlпоміщується пробіл (символ виводу)
push cx ; збереження cxв стеку
mov cx,4 ; поміщення в cxкількості символів для
; виводу (4)
callWriteSimv ; вивід 4-х пробілів
popcx ; відновлення cx
jmp@@03 ; перехід
@@02:
movdi,offsetpoint ; в diпоміщується зміщення змінної point
pushcx ; збереження cx
callStrWrite ; вивід на екран зірочки
pop cx ; відновлення cx
@@03:
loop @@01 ; виконувати цикл, доки cx≠0 (6-ть разів)
; ------Вивід години створення файлу
movbx,[offsetdirData+ FileName-8] ; в bxпоміщується слово часу
; створення файлу
mov ax,bx ; в axпоміщуються слово години
; створення файлу
andax,0f800h ; накладання маски
shrax,11 ; зсув результату (отримали години)
movcx,1
movdi,offsetbuffer ; diвказує на пустий буфер buffer
callBinToAscDec ; передача в змінну buffer10-кового
; ASCII-представлення числа з ax
mov cx,2 ; в cxширина поля виводу
callStrWrite2 ; вивід ASCII-представлення числа з ax
mov cx,1 ; встановлення в cxкількості виводів
mov dl, ':' ; передача в dlсимволу, що виводиться
call WriteSimv ; вивід один раз символу із dl
; ------Вивід хвилин створення файлу
movax,bx ; в axпоміщується слово хвилини
; створення файлу
and ax,7e0h ; накладання маски
shr ax,5 ; зсув результату (отримали хвилини)
movcx,1
movdi,offsetbuffer ; diвказує на пустий буфер buffer
callBinToAscDec ; передача в змінну buffer10-кового
; ASCII-представлення числа з ax
mov cx,2 ; в cxширина поля виводу
callStrWrite2 ; вивід ASCII-представлення числа з ax
mov cx,1 ; встановлення в cxкількості виводів
mov dl, ':' ; передача в dlсимволу, що виводиться
call WriteSimv ; вивід один раз символу із dl
; ------Вивід секунд створення файлу
mov ax,bx ; в axпоміщується слово секунди
; створення файлу
and ax,1fh ; накладання маски
shl ax,1 ; помноження на 2 (отримання секунд із
; двохсекундних одиниць)
movcx,1
movdi,offsetbuffer ; diвказує на пустий буфер buffer
callBinToAscDec ; передача в змінну buffer10-кового
; ASCII-представлення числа з ax
mov cx,3 ; в cxширина поля виводу
callStrWrite2 ; вивід ASCIIпредставлення числа з ax
mov cx,1 ; встановлення в cxкількості виводів
mov dl, ' ' ; передача в dlсимволу, що виводиться
call WriteSimv ; вивід один раз символу із dl
; ------Виведення дня створення файлу
movbx,[offsetdirData+ FileName-6] ; в bxслово дати створення
; файлу
mov ax,bx ; в axслово дня створення файлу
andax,01fh ; накладання маски
movcx,1 ; встановлення мінімальної довжини
; перетворюваного рядка
movdi,offsetbuffer ; в diзміщення пустого буферу
callBinToAscDec ; заповнення буферу buffer10-ковим
; ASCII-представленням числа з ax
mov cx,2 ; в cxширина поля виводу
call StrWrite2 ; вивід ASCIIпредставлення номера дня
mov cx,1 ; в cxкількість виводів
mov dl, '\' ; в dlсимвол для виводу
callWriteSimv ; вивід символу із dlзадану кількість разів
; ------Вивід місяця створення файлу
movax,bx ; в axслово місяця створення файлу
andax,1e0h ; накладання маски
shrax,5 ; зсув результату (отримання місяця)
mov cx,1 ; встановлення мінімальної довжини
; перетворюваного рядка
movdi,offsetbuffer ; в diзміщення пустого буферу
callBinToAscDec ; заповнення буферу buffer10-ковим
; ASCII-представленням числа з ax
mov cx,2 ; в cxширина поля виводу
call StrWrite2 ; вивід ASCIIпредставлення номера дня
mov cx,1 ; в cxкількість виводів
mov dl, '\' ; в dlсимвол для виводу
callWriteSimv ; вивід символу із dlзадану кількість разів
; ------Вивід року створення файлу
movax,bx ; в axслово року створення файлу
andax,0f800h ; накладання маски
shrax,9 ; зсув результату (отримання року)
add ax,1980 ; отримання року створення
mov cx,1 ; встановлення мінімальної довжини
; перетворюваного рядка
movdi,offsetbuffer ; в diзміщення пустого буферу
callBinToAscDec ; заповнення буферу buffer10-ковим
; ASCII-представленням числа з ax
mov cx,4 ; в cxширина поля виводу
call StrWrite2 ; вивід ASCIIпредставлення номера дня
mov cx,2 ; в cxкількість виводів
mov dl, ' ' ; в dlсимвол для виведення
call WriteSimv ; вивід проміжку у 2-а пробіли
; ------Вивід розміру файлу у 16-річному вигляді
movax,[offsetdirData+ FileName-2] ; в axмолодші два байти
; подвійного слова розміру файла
mov cx,1 ; в cxмінімальна довжина
; перетворюваного рядка
mov di,offset buffer ; в diзміщення буферу для результату
call BinToAscHex ; перетворення двох молодших байтів
; розміну у ASCII-рядок
callStrWrite ; вивід на екран
movax,[offsetdirData+ FileName-4] в axмістяться старші два байти
; подвійного слова розміру файла
callBinToAscHex ; перетворення у ASCIIрядок
; представлення у вигляді 16-річного
; числа
callStrWrite ; вивід на екран
callNewLine ; перехід на новий рядок
pop bx ; відновлення у bxзміщення процедури
; Action
ret ; завершення процедури
ENDP Action
END Start
Схема алгоритму основної програми приведена у додатках (Додаток А).
Отримання даних із командного рядку і встановлення критерію відбору файлів (маски) реалізується за допомогою функцій модуля PARAMS.obj. Спочатку заповнюється спеціальний буфер хвостом команди і його вміст розбивається на окремі елементи (GetParams). При наявності в хвості команди параметрів, перший параметр задає маску; якщо параметри відсутні, у якості маски встановлюється стандартна '*.*'(вивід всіх файлів із директорії, в якій знаходиться програма). Основну роботу виконує функція DirEngine, в яку, за допомогою регістру bx, передається зміщення функції Action(для подальшого виклику її за зміщенням).
Функція DirEngine, за допомогою 2Fh, 1Ah, 4Eh, 4Fhфункцій переривання INT21hDOS, знаходить поточне положення буфера DTA, зберігає його адресу, встановлює новий DTAу власний спеціальний буфер і за допомогою нього шукає файли, що відповідають заданій масці. При знаходженні таких файлів, керування по зміщенню передається функції Action.
Основна задача Action– обробити інформацію в DTAі вивести необхідні дані на стандартний пристрій виводу.
DTA має наступну структуру [4, 6]:
Зміщення | Довжина | |
+0 | 15H | Зарезервована, використовується функцією 4FhINT21hDOS |
+15h | 1 | атрибут файла |
+16h | 2 | час |
+18h | 2 | дата |
+1ah | 4 | розмір файла (формат DWORD) |
+1eh | 0dh | 13-байтова ASCIIZім'я файлу |
Спочатку виводиться ім'я файлу, яке має наступну структуру: "filename.ext". Вивід реалізується за допомогою спеціальних функцій StrWrite, StrWriter, Lengthі WriteSimvіз модуля STRIO.obj.
Наступним кроком реалізується вивід атрибутів файлу шляхом виводу зірочок навпроти відповідного атрибуту. Байт атрибуту файлу має наступну структуру[6]: