Смекни!
smekni.com

Розробити програму-аналог програми Doc Undelete (стр. 4 из 4)

5. Реалізація програми

Програма написана на мові ASM-86 з використанням команд процесора 286/386. Вона складається з головної програми, яка перевіряє параметр - файл, який потрібно відновити, знаходить цей файл, якщо він є, серед вилучених, та відновлює його.

Програма компілюється Turbo Assembler, зв’язується за допомогою TLINK.

6. Системні вимоги

IBM сумісний комп’ютер із мікропроцесором Intel 80386 або старшим.

Для перегляду результатів - Turbo Debugger або інший відлагоджувач.

7. Інструкція для користувача

Для запуску програми, яка дозволяє відновлювати файли, треба в командному рядку набрати UNDEL.com потім, через проміжок набрати ім'я файлу, який треба відновити на диску a, та натиснути Enter. Програма перевірить, чи є таке ім'я на диску серед вилучених файлів, і якщо є, то відновить його.

8. Висновки

Отже, є розробленою програма, яка виконує відновлювання вилучених файлів. Також був розглянутий алгоритм відновлювання файлів, які були вилучені. По перерахованим вище кроках може показатися, що процедура відновлення файлів є досить прямолінійної. У залежності від наявних у вашому розпорядженні програмних інструментів, у дійсності однак перегляд даних на диску й запис інформації на диск може бути складним заняттям. Відзначимо тут, що кроки 6 і 7 містять застереження про можливість того, що трохи раніше стертих файлів можуть переплестися через складну послідовність розташування їхніх кластерів. Відновлення переплутаних даних зазначеним вище способом може виявитися дуже нудотним і в той же час головоломним заняттям. Але при наявності терпіння (можливо усього лише невеликого!), і, змусити себе бути методичним, ви неодмінно зможете розплутати файли.

9. Використана література

1) “Програмування на мові Асемблера ЕС ЕВМ" З.С. Брич. В.I. Воющ Москва 1989 р. ст.166

2) “Програмування на сучасних мовах програмування. ” Москва 1990р. ст. 206

3) “Основи мови” Асемблер” В.I. Криволап. Москва 1997р. ст.309

4) “Ассемблер для початкiвцiв” М.П. Шукiн. Київ 1980р. ст.155

5) “Турбо Асемблер” Л.В. Захаров. Харків 1995 р ст.178

6) “Макро Асемблер” К.С. Кропiйко О.Д. Богатирова. Київ - “Наука” 1991р.

7) Електронний довідник BOOK.

Додаток

Лістинг програми

FCB_LOC EQU 5CH; Положение FCB для удаленного файла в PSP

SWITCH_LOC EQU 81H; Положение командного рядка

CR EQU 13; ASCII возврат каретки

LF EQU 10; ASCII перевод строки

CODE_SEG SEGMENT

ASSUME CS: CODE_SEG,DS: CODE_SEG,ES: CODE_SEG

ORG 100H

ENTRY: JMP FIRST; пропуск данных

I_O_FLAG DW?; Выбор чтения или записи кластеров

START_CLUSTER DW?; Первый кластер удаленного файла

FILE_SIZE DW?; Размер файла в кластерах (1 кластер =1 сектору)

DISK_DRIVE DB 0; Диск для удаленного файла

NOT_FOUND_MSG DB 13,'File not found deleted$'; Messages

WRITTEN_OVER_MSG DB 13,'File already written over$'

DATA DB 1024 DUP (0); Место под directory и FAT

FIRST:; Начало программы

UNDEL PROC NEAR

MOV AL,CS: FCB_LOC; Получить drive specified - 0 если one given

SUB AL,1; Was it a 1 (A:) or 2 (B:)?

JNC DRIVE_KNOWN; Yes, store drive number

MOV AH, 19H; Нет, получить диск по умолчанию

INT 21H

DRIVE_KNOWN:

MOV DISK_DRIVE,AL; Запомнить диск

MOV DX,17; Директории начинаются с 19 сектора

LOOPs: ADD DX,1; Переход к следующему кластеру директории

CMP DX,33; Проверка на последний кластер директории

JB READ_DIR; Если не последний, переход на чтение

MOV AH,9; Иначе выходим с выдачей сообщения,

LEA DX,NOT_FOUND_MSG; о том, что файл не найден

INT 21H

JMP OUT1; Exit

READ_DIR:

AND I_O_FLAG,0; Выбираем чтение

CALL CLUSTER_I_O; Читаем кластер

LEA DI,DATA; Загружаем адрес проверки

MOV AL,0E5H; Символ проверки - первый символ удаленного файла E5H

MOV CX, 200H; Количество символов проверки 512

SEARCH:;

REPNE SCASB; Проверка

JCXZ LOOPs; If no match (Counter=0), get next dir cluster

MOV SI,FCB_LOC+2; Сравнение со 2 символа на совпадение имен файлов

MOV BX,11; Сравнение 11 символов

CMPLOOP: DEC BX; уменьшить количество сравниваемых символов

CMPS byte ptr [DI], [SI] ; Сравнить файлы

JZ CMPLOOP; Если совпадают, переход на следующий чимвол

CMP BX,0; Сравнение закончено, все символы проверены?

JNZ SEARCH; Нет, переход на продолжение поиска

MOV AX,CS: FCB_LOC+1; Да, получить первый символ файла

MOV [DI-12],AX; Заменить символ E5H на первыый символ файла

OR I_O_FLAG,1; Выбрать запись 1 кластера

CALL CLUSTER_I_O; Запись измененной директории

MOV AX, [DI+14] ; Получить начальный сектор в FAT

MOV START_CLUSTER,AX; Запомнить начальный сектор FAT

MOV AX, [DI+16] ; Получить размер файла (младшее слово)

TEST AX,511; MOD (size,512) =0?

JZ EVEN_K; Да, не добавлять 1 кластер после SHR

ADD AX,512; Нет, добавлять другие кластера

EVEN_K: MOV CL,9; Деление на 512 (512=размер кластера)

SHR AX,CL

MOV DX, [DI+18] ; Получить размер файла (старшее слово)

MOV CL,7; Умножение на 128 (2^16/2^9)

SHL DX,CL

ADD AX,DX; Добавить старшее слово до младшего слова

MOV FILE_SIZE,AX; Сохранить размер

MOV DX,1; Прочитать FAT

AND I_O_FLAG,0; Выбор чтения 1 кластера

CALL CLUSTER_I_O

MOV CX,FILE_SIZE; Счетчик количества кластеров

MOV AX,START_CLUSTER; Проверка на то, что первый кластер свободный

DEC AX;

CALL GET_NEXT_ZERO;

CMP DX,START_CLUSTER

JE FILL; Если свободный, переход на заполнение FAT

MOV AH,13H; Нет, файл перезаписуется

MOV DX,FCB_LOC; Удаляется сохраненная запись директории

INT 21H;

MOV AH,9; Выход с ошибкой

LEA DX,WRITTEN_OVER_MSG

INT 21H

JMP OUT1; переход на выход

FILL: MOV AX,DX; Установить старое свободное пространство в FAT на первый найденный

MOV DX,0FFFH; Указать, что это последний кластер (FFFH=End of file)

CMP CX,1; Если последняя запись? (CX=количество кластеров)

JZ LAST; Да, не надо шукать следующую свободную запись

CALL GET_NEXT_ZERO; Вызов с AX=старый 0 кластер. Возвращает DX=новый 0 кластер

LAST: CALL PUT_FAT_ENTRY; Вызов с AX=старый 0 кластер. Возвращает DX=новый 0 кластер в FAT

LOOP FILL; Обработать следующий кластер

MOV DX,1; Запись измененной 1 копии FAT

OR I_O_FLAG,1; Выбор записи кластера

CALL CLUSTER_I_O; Запись кластера

MOV DX,3; Запись измененной 1 копии FAT

CALL CLUSTER_I_O; Запись кластера

OUT1: INT 20H; Выход

UNDEL ENDP

CLUSTER_I_O PROC NEAR; Чтение кластера

; Вход: DX-начальный сектор

PUSH AX; Сохранить используемые регистры в стеке

PUSH BX; INT 25H изменяет все регистры

PUSH CX

PUSH DX

PUSH DI

MOV AL,DISK_DRIVE; Получить номер диска

MOV CX,1; 1 сектор

LEA BX,DATA; Адрес буфера

TEST I_O_FLAG,1; Проверка на чтение/запись

JNZ WRITE; переход на запись

INT 25H; Чтение секторов

JMP POPOUT; выход с процедуры

WRITE: INT 26H; запись секторов

POPOUT: POPF; убрать из стека

POP DI; восстановить регистры

POP DX

POP CX

POP BX

POP AX

RET; Выход

CLUSTER_I_O ENDP

GET_NEXT_ZERO PROC NEAR; Поиск следующей нулевой записи FAT

; Вход: AX-FAT номер записи (кластер)

; Выход: следующий ноль в DX

PUSH AX; Сохранить используемые регистры в стеке

PUSH BX

PUSH CX

CHECK_NEXT:; Поиск

INC AX; AX начало сдедующей записи

MOV BX,AX; Получить 3/2*AX для действительного смещения в FAT

SHL BX,1;

ADD BX,AX

SHR BX,1; BX - значение смещения записи FAT in AX

MOV DX,WORD PTR DATA [BX] ; в DX записеется значение записи FAT

TEST AX,1; Запись четная?

JZ EVEN_ENTRY; Да, использовать младшие 12 bits

MOV CL,4; Нет, использовать старшие 12 bits

SHR DX,CL

EVEN_ENTRY:

AND DX,0FFFH; Получить младшие 12 bits

CMP DX,0; значение FAT =0?

JNE CHECK_NEXT; Нет, переход к следующему кластеру

MOV DX,AX; Поместить значение записи из AX

POPS: POP CX; восстановить регистры

POP BX

POP AX

RET

GET_NEXT_ZERO ENDP

PUT_FAT_ENTRY PROC NEAR; Запись новой FAT записи в FAT

; Получает номер уластера FAT в AX и новую запись в DX

PUSH AX; Сохранить используемые регистры в стеке

PUSH BX

PUSH CX

PUSH DX

MOV BX,AX; Получить смещение в FAT, 3*AX/2

SHL BX,1; Умножить на 2

ADD BX,AX; Добавит AX для получения 3*AX

SHR BX,1; Деление на 2 - BX содержит значение смещения FAT

TEST AX,1; Четный номер?

JZ P_EVEN_ENTRY; Да, использовать младшие 12 bits

MOV CL,4; Нет, использовать старшие 12 bits

SHL DX,CL

P_EVEN_ENTRY:

OR WORD PTR DATA [BX],DX; Записать номер кластера в FAT

POP DX; восстановить регистры

POP CX

POP BX

POP AX

RET

PUT_FAT_ENTRY ENDP

CODE_SEG ENDS

END ENTRY