№ біту | Що означає |
0 | тільки читання |
1 | скритий |
2 | системний |
3 | том |
4 | каталог |
5 | архів (або копія файлу не створювалась) |
Тобто, якщо біт атрибуту файлу буде мати наступне значення 21h, це означатиме, що файл є архівним, він лише для читання.
Передостаннім кроком виводяться час і дата створення файлу у форматі: година:хвилина:секунда день\місяць\рік. Дані, що описують час і дату створення/змінення файлу, потребують накладання масок і здвигів для
№ біта | Операція | № біта | Операція | ||
Час створення | Дата створення | ||||
15 | година(0-23) | (t & 0f800h)>>11 | 15 | рік(0-119)+1980 | d & 001fh |
14 | 14 | ||||
13 | 13 | ||||
12 | 12 | ||||
11 | 11 | ||||
10 | хвилина(0-59) | (t & 07e0h)>>5 | 10 | ||
9 | 9 | ||||
8 | 8 | місяць(1-12) | (d & 01e0h)>>5 | ||
7 | 7 | ||||
6 | 6 | ||||
5 | 5 | ||||
4 | секунда / 2(0-30) | t & 001fh | 4 | день(0-31) | (d & f800h)>>9 |
3 | 3 | ||||
2 | 2 | ||||
1 | 1 | ||||
0 | 0 |
отримання необхідної інформації і представлені в наступному виді [6]:
Перевід двійкових чисел у ASCII-десяткове представлення для виводу на екран реалізується за допомогою функції BinToAscDecмодуля BINASC.obj.
Останній крок виводу розміру файлу виконується в два етапи, оскільки розмір файлу міститься у подвійному слові і модуль BSNASC.objне надає інструменту для переведення двійкових даних у ASCII-рядок.
Спочатку за допомогою функції BinToAscHexмодуля BINASC.objпереводиться молодші, а потім старші два байти, переведені у ASCII-шістнадцятирічне представлення.
По завершенні своєї роботи Actionзнов передає керування викликаючій функції DirEngin, яка повторює пошук файлів і викликає для роботи Action, доки не завершить обробку всіх файлів, що відповідають масці. Після цього DirEngineповертає старий DTAі передає курування основній програмі, яка завершує роботу і повертає код виходу.
Результати роботи програми:
D:\Program\ASM\misk>dr
The DIRWUER wersion 1.0
Romanov Alexander Urievich. KIT-13A NTU"KhPI"
Copyright (C) 2005 by Romanov Alexander
Filename OnR Skr Sys Tom Kat Arh Time Data Size
. * 11:59:18 11\5 \2005 00
.. * 11:59:18 11\5 \2005 00
BLW32.DLL * 12:12:0 14\5 \1996 52020
DEBUG.EXE * * 22:22:0 5 \5 \1999 0518A
USA.BLL * 12:12:0 14\5 \1996 18DCD
MYREP.CBA * 18:48:42 25\1 \2002 01F
DIRECT * 12:27:54 11\5 \2005 00
CATALOG3.CAB * * 22:22:0 5 \5 \1999 425C3
SUHELPER.BIN * * 22:22:0 5 \5 \1999 05C0
SAVE32.COM * * 22:22:0 5 \5 \1999 0398
ASD.LOG * * 13:8 :20 11\8 \2004 0162
IO.SYS * * * 22:22:0 5 \5 \1999 364B6
MSDOS.SYS * * * * 18:30:28 16\7 \2004 0697
08-APRIL.MP3 * 11:42:44 7 \12\2003 B11100
DR.EXE * 12:14:28 11\5 \2005 05A1
DR.BAT * 12:54:34 4 \5 \2005 09B
D:\Program\ASM\misk>dr.exe *.exe
The DIRWUER wersion 1.0
Romanov Alexander Urievich. KIT-13A NTU"KhPI"
Copyright (C) 2005 by Romanov Alexander
Filename OnR Skr Sys Tom Kat Arh Time Data Size
DEBUG.EXE * * 22:22:0 5 \5 \1999 0518A
DR.EXE * 12:14:28 11\5 \2005 05A1
D:\Program\ASM\misk>dr s*.???
The DIRWUER wersion 1.0
Romanov Alexander Urievich. KIT-13A NTU"KhPI"
Copyright (C) 2005 by Romanov Alexander
Filename OnR Skr Sys Tom Kat Arh Time Data Size
SUHELPER.BIN * * 22:22:0 5 \5 \1999 05C0
SAVE32.COM * * 22:22:0 5 \5 \1999 0398
D:\Program\ASM\misk>dr d:\program\asm\misk\direct\*.*
The DIRWUER wersion 1.0
Romanov Alexander Urievich. KIT-13A NTU"KhPI"
Copyright (C) 2005 by Romanov Alexander
Filename OnR Skr Sys Tom Kat Arh Time Data Size
. * 12:27:54 11\5 \2005 00
.. * 12:27:54 11\5 \2005 00
BINASC.ASM * 11:3 :40 8 \5 \2005 0300
PARAMS.ASM * 13:31:20 6 \5 \2005 04E4
TD.EXE * 14:39:40 24\12\2002 784F0
Як видно із приведених результатів програма DR.EXEза умовчанням виводить весь вміст директорії, в якій вона розташована (приклад 1). Інші приклади демонструють різноманітні засоби виклику програми із заданням різноманітних масок, використовуючи символи "*" і "?". Останній приклад демонструє, що виклик DR.exeможна реалізувати і з маскою, що задає повний шлях до директорії, інформацію про яку необхідно вивести.
Таким чином, розроблена програма DR.exeповністю відповідає поставленому завданню про створення програми мовою асемблера, яка виводить вміст директорії, атрибути, розмір і час/дату створення файлів і папок, які в ній містяться.
4. Розробка задачі на мові високого рівня із використанням асемблерних фрагментів коду
Як показала третя глава, розробка програми чисто на асемблері є складним процесом і потребує розробки супутніх (допоміжних) модулів для реалізації моментів, що не пов’язані із основним алгоритмом задачі (таких, як вивід на екран, перетворення двійкових даних у ASCII-рядки, тощо). Мови високого рівня дають можливість реалізувати все автоматично [3]. Такий стан речей спонукає розробити програму, в якій основний алгоритм пошуку DTAі необхідних файлів, що відповідають масці, реалізовані асемблерними вставками, а задачі, пов’язані із розробкою інтерфейсу і виводу даних на екран, реалізовані, наприклад, мовою Pascal.
4.1. Розробка програми на Pascal
Мова Pascalдає можливість створити вказівник типу "запис" (поля "запису" описують атрибут, час, дату, розмір і ім'я файлу) прямо на стандартний буфер DTA, не створюючи власного і не виконуючи зайвих дій по встановленню нової адреси буфера DTAі відновлення старої після завершення програми. Вивід інформації про файл довіряється процедурі, яка обробляє поля вказівника на DTAі виводить дані стандартними функціями Pascal.
На початку програми є сенс запитувати користувача про бажання задати власну маску для файлів, або лишити стандартну ("*.*").
Згідно із зазначеними змінами було розроблено програму DIRWUER.pas, приведену нижче:
{DIRWUER.pas}
Usescrt;
{------FindFirst – шукає перше входження файлу, що відповідає заданій масці}
Function FindFirst (Path : PChar) : Boolean; assembler;
asm
mov ah, 4Eh{в ahномер функції першого пошуку}
mov cx, 3fh{в cxмаска для всіх атрибутів файлу}
mov dx, word ptr Path{dxвказує на маску файлу}
int 21h{виклик функції першого пошуку файлу}
mov al, 0{в alпоміщується 0 – код помилки(false)}
jc @Failed {якщо помилка, повернути код помилки,}
inc al{інакше повернути 1 – true}
@Failed:
end;
{------FindNextшукає наступне входження файлів, маска і атрибути яких були задані при попередньому пошуку.}
FunctionFindNext: Boolean; assembler;
asm
movah, 4Fh{в ahномер функції наступного пошуку }
{файлу}
int 21h{пошук наступного файлу за параметром,}
{заданим функцією 4Eh}
moval, 0 {в alпоміщується 0 – код помилки (false)}
jc @Failed {повернути код помилки, якщо помилка}
inc al {інакше повернути 1 – true}
@Failed:
end;
Type
DTA = record{запис описує структуру DTA-буфера}
Reserved : Array[0..$14] of Byte;{резервна область пам'яті}
Attrib : Byte;{поле атрибуту}
Time : Word; {поле часу створення}
Date : Word; {поле дати}
Size : Longint;{розмір}
Name : Array[0..$C] of Char;{ім'я файлу із розширенням}
end;
PDTA= ^DTA; {вказівник на буфер DTA}
{------GetDTAAddressповертає адресу буфера DTA}
FunctionGetDTAAddress: PDTA; assembler;
asm
movah, 2Fh {в ahномер функції пошуку DTA}
int21h {отримання в as:bxадреси DTA}
pushes {в dxчерез стек передаються дані із es}
popdx
movax, bx {передача в axданих із bx}
{в dx:axповертається результат}
end;
Var
DTAAddress : PDTA;
s : string;
Path : PChar;
i : byte;
Label 1;
{------Процедура виводу даних о файлі/директорії згідно із інформацією в DTA}
Procedure ShowEntry;
Begin
Write(DTAAddress^.Name:13,' ');{вивід імені файлу із розширенням}
for i:= 0 to 5 do
if (DTAAddress^.Attrib and (1 shl i)) <>0
then write(' * ') {вивід зірочок навпроти файлів }
else write(' '); {із відповідними атрибутами}
{------Вивід часу створення файлу}
Write(' ',((DTAAddress^.Time and $0f800)shr 11):2);
Write(':',((DTAAddress^.Time and $07e0)shr 5):2,':');
Write(((DTAAddress^.Time and $1f)shl 1):2);
{------Вивід дати створення файлу}
Write(' ',(DTAAddress^.Date and $1f):2,'/');
Write(((DTAAddress^.Date and $01e0)shr5):2,'/');
Write((((DTAAddress^.Dateand$0f800)shr9)+$07bc):4);
Writeln(' ',DTAAddress^.Size:7); {вивід розміру файлу}
end;
BEGIN
ClrScr; {очистка екрану}
{------Вивід інформації о програмі}
Writeln('The DIRWUER wersion 1.0');
Writeln('Romanov Alexander Urievich. KIT-13A KHPI');
Writeln('Copyright (C) 2005 by Romanov Alexander');
DTAAddress := GetDTAAddress;{встановлення вказівника}
{на адресу DTA}
1:
Write('Input the mask (default: *.*; exit: q): '); {запит на введення маски}
Readln(s); {отримання відповіді}
if s='' then Path:='*.*'{якщо відповіді не має,}
{встановлення стандартної маски}
else if s='q' then halt {якщо відповідь 'q', завершення}
{роботи програми}
else Path:=Addr(s[1]); {встановлення заданої маски}
if FindFirst (Path)then {знаходження першого файлу}
begin
Write('Filename OnR Skr Sys Tom ');
Writeln('Kat Arh TimeDataSize'); {вивід заголовка таблиці}
ShowEntry; {вивід на екран даних про файл}
while FindNext do ShowEntry;{доки знайдено наступний файл,}
{виводити дані про нього на екран}
end
elsewriteln('Failed');{інакше, при незнаходженні}
{жодного файлу, виводиться}
{повідомлення про їх відсутність}
goto 1; {перехід на початок}
END.
Схема алгоритму програми приведена в додатках (Додаток Б).
Програма реалізує запит на введення маски файлу і, згідно із реакцією користувача, встановлює стандартну маску, або введену користувачем. При відповіді q– програма завершується.
Після задання маски встановлюється вказівник на DTA-буфер, після чого програма реалізує пошук файлів, що відповідають масці і вивід даних на екран. Потім програма повертається до початкового кроку запиту нової маски файлів для наступних дій.
Результати роботи програми проілюструємо наступним чином:
The DIRWUER wersion 1.0
Romanov Alexander Urievich. KIT-13A KHPI
Copyright (C) 2005 by Romanov Alexander
Input the mask (default: *.*; exit: q):
Filename OnR Skr Sys Tom Kat Arh Time Data Razmer
. * 11:59:18 11/5 /2005 00
.. * 11:59:18 11/5 /2005 00
BLW32.DLL * 12:12:0 14/5 /1996 52020
DEBUG.EXE * * 22:22:0 5 /5 /1999 0518A
USA.BLL * 12:12:0 14/5 /1996 18DCD
MYREP.CBA * 18:48:42 25/1 /2002 01F
DIRECT * 12:27:54 11/5 /2005 00
CATALOG3.CAB * * 22:22:0 5 /5 /1999 425C3
SUHELPER.BIN * * 22:22:0 5 /5 /1999 05C0
SAVE32.COM * * 22:22:0 5 /5 /1999 0398
ASD.LOG * * 13:8 :20 11/8 /2004 0162
IO.SYS * * * 22:22:0 5 /5 /1999 364B6
MSDOS.SYS * * * * 18:30:28 16/7 /2004 0697
08-APRIL.MP3 * 11:42:44 7 /12/2003 B11100
DR.EXE * 12:14:28 11/5 /2005 05A1
DR.BAT * 12:54:34 4 /5 /2005 09B
DIRWUER.EXE * 13:48:38 13/ 5/2005 6256
Input the mask (default: *.*; exit: q): *.b??
Filename OnR Skr Sys Tom Kat Arh Time Data Razmer
USA.BLL * 12:12: 0 14/ 5/1996 101837
SUHELPER.BIN * * 22:22: 0 5/ 5/1999 1472
DR.BAT * 12:54:34 4/ 5/2005 155
Input the mask (default: *.*; exit: q): direct/*.*
Filename OnR Skr Sys Tom Kat Arh Time Data Razmer
. * 12:27:54 11/ 5/2005 0
.. * 12:27:54 11/ 5/2005 0
BINASC.ASM * 11: 3:40 8/ 5/2005 768