
Шустрый

Профиль
Группа: Участник
Сообщений: 111
Регистрация: 18.4.2008
Где: Харьков - СС_3
Репутация: нет Всего: 1
|
Алгоритм работает через COM файл, часть кода уже была только немного преобразовал исходный алгоритм - FAQКод | ; tasm /m scantree.asm ; tlink /t /x scantree.obj
.MODEL Tiny .286 .CODE ORG 100h
LOCALS
PathLen = 100 ; Максимальный путь к файлу/каталогу ; (уменьшать это значение нежелательно) Start: mov ah,09h ; lea dx,vvyr ; int 21h ; выводим приглашение mov ah,01h ; ожидаем ввода клавиши PS вводите только цифру т.к. проверки нет int 21h sub al,30h ; переводим из ASCII в число add al,1 ; так надо mov MAX_U_V,al ; записываем значение в MAX_U_V mov U_V,0 ; записываем нулевой уровень push offset MyFunc ; вывод персоначальной директории call ScanTree ; первый вызов Сканирования директории int 20h
mov ah,01h int 21h
MyFunc proc lea di,ScanPath ; DI = адрес строки ScanPath push di mov cx,PathLen xor al,al repne scasb ; Ищем конец строки dec di mov word ptr [di],0A0Dh ; Записываем туда CR,LF... mov byte ptr [di+2],'$' ; ...и символ доллара (для ф-ии 9) pop dx push dx mov ah,9 int 21h ; Выводим строку на экран
pop dx mov byte ptr [di],0; Восстанавливаем строку ScanPath ; (т.к. изменять ее нельзя) ret MyFunc endp
; Маски атрибутов файлов/каталогов faReadOnly = 1 faHidden = 2 faSystem = 4 faVolume = 8 faDirectory = 10h faArchive = 20h faAnyFile = faReadOnly+faHidden+faSystem+faArchive faAnyDir = faAnyFile+faDirectory faAnithing = faAnyDir+faVolume
; Описание буфера DTA DTAFileInfo struc dtaReserved db 21 dup (?) dtaAttr db ? dtaTime dw ? dtaDate dw ? dtaSize dd ? dtaName db 13 dup (?) ends
ScanTree proc pascal arg Func:word local OldDTA:dword, NewDTA:DTAFileInfo ; ES всегда равно первоначальному DS !!! push ds ; Сохраняем DS inc U_V mov ah,2Fh int 21h ; Получаем адрес DTA mov word ptr OldDTA[0],bx ; Сохраняем его... mov word ptr OldDTA[2],es ; ...в переменной OldDTA pop es ; Восстанавливаем DS в регистр ES (ES=DS) lea di,ScanPath mov cx,PathLen xor al,al cld ; Прямой порядок поиска scasb repne scasb ; Ищем в имени каталога нулевой байт (конец строки) dec di push di ; Сохраняем указатель на ноль push ds es ; Сохраняем DS и ES call Func ; Вызываем функцию для стартового каталога mov ah,1Ah push ss pop ds ; DS = SS (сегмент NewDTA) lea dx,NewDTA int 21h ; Устанавливаем свой DTA pop es ds ; Восстанавливаем DS и ES (ES=DS) mov ah,4Eh ; Готовимся в началу поиска mov cx,faAnyDir ; Атрибуты (все, кроме Volume label) lea dx,ScanPath lea si,ScanMask ; SI = адрес макси поиска pop di ; Восстанавливаем DI (указатель на конец строки)... push di ; ...и тут же сохраняем его cld ; Прямой порядок работы lodsb/stosb @@CopyMask: lodsb ; Читаем в AL символ из строки [SI] stosb ; И записываем его в конец ScanPath or al,al ; Конец строки [SI] (AL=0) ? jnz @@CopyMask ; Нет, копируем следующий символ @@FindNext: int 21h ; Начинаем/продолжаем поиск jc @@NotFound ; Выходим, если ничего не найдено (CF=1) push ss pop ds ; DS = SS (сегмент NewDTA)
test NewDTA.dtaAttr,faDirectory ; Проверяем - каталог ли был найден jz @@PrepareNext ; Если нет, готовимся продолжать поиск lea si,NewDTA.dtaName ; Адрес имени найденного файла/каталога lodsb ; Читаем первый символ
;----------------------- mov hh,ah ; сохраняем ah в hh mov ah,U_V ; в ah записываем текущую вложенность cmp ah,MAX_U_V ; сравниваем это значение с максимальной jl GGG ; если оно меньше то идём далее без изменений с метки GGG mov al,'.' ; если всё же больше или равны то изминяем имя каталога на точку GGG:mov ah,hh ; возращаем ah её первоначальное состояние ;----------------------- cmp al,'.' ; Это каталоги '.' и '..'? (нам такие не нужны) je @@PrepareNext ; Если это они, готовимся продолжать поиск pop di ; Восстанавливаем DI (указатель на конец строки)... push di ; ...и тут же сохраняем его @@CopyPath: stosb ; Записываем символ строки [SI] в конец ScanPath lodsb ; Читаем в AL символ из строки [SI] or al,al ; Конец строки [SI] (AL=0) ? jnz @@CopyPath ; Нет, копируем следующий символ mov ax,'\' ; AH = 0, AL = '\' stosw ; Записываем слэш и ноль в конец строки push es pop ds ; DS = ES push Func call ScanTree ; Вызываем себя рекурсивно push ss pop ds ; DS = SS (сегмент NewDTA) @@PrepareNext: mov ah,4Fh ; Готовимся к функции 4Fh lea dx,NewDTA jmp @@FindNext ; Продолжаем поиск @@NotFound: pop di ; Убираем из стека DI mov ah,1Ah lds dx,OldDTA int 21h ; Восстанавливаем DTA dec U_V ; УМЕНЬШАЕМ ЗНАЧЕНИЕ ВЛОЖЕННОСТИ push es pop ds ; Восстанавливаем первоначальный DS ret ; Выходим из процедуры ScanTree endp
.DATA U_V db ? ; вложенность текущего каталога MAX_U_V db ? ; максимальная вложенность hh db ? ; для временного хранения регистра ah пока я его использую ScanMask db '*.*',0 ; Маска каталогов для поиска StartPath db 'C:\',0 ; Стартовый каталог ORG StartPath ; Совмещаем StartPath и ScanPath ScanPath db PathLen dup (?) ; ASCIIZ-имя найденного каталога filen db 'C:\Direct.txt',0 ; файл в который идет запись filed dw ? ffile db 13,10 vvyr db 'Vvedite yroven vloennotigsti >> $' exit: mov ah,08h int 21h mov ax,4c00h int 21h END Start
|
Если Кто нибуть сделает или знает нормальный алгоритм и он работает через EXE-файл напишите его!!!
|