TASM иерархия каталогов диска
Модераторы: Хыиуду, MOTOCoder, Medved, dr.Jekill
Необходимо вывести на экран иерархию каталогов. Если я правильно понимаю,то надо сначала получить список файлов корневого каталога,потом проверить атрибуты файлов,если директория,то выводить путь и открывать файл, и так же действовать уже в открытом.Насущный вопрос щас - что использовать и куда обращаться чтоб получить список файлов корневого каталога?
- Naeel Maqsudov
- Сообщения: 2570
- Зарегистрирован: 20 фев 2004, 19:17
- Откуда: Moscow, Russia
- Контактная информация:
Зависит от ОС.
По ДОС есть потнясающая книга "Пришем вирус и антивирус"
http://vx.netlux.org/lib/apk01.html
См. там главу 2.6 про функции DOS (прерывание 21h) 4Eh (Find first matching file) и 3Eh (Find next matching file)
По ДОС есть потнясающая книга "Пришем вирус и антивирус"
http://vx.netlux.org/lib/apk01.html
См. там главу 2.6 про функции DOS (прерывание 21h) 4Eh (Find first matching file) и 3Eh (Find next matching file)
Я бы посоветовал использовать FCB и функции 11h и 12h
It's a long way to the top if you wanna rock'n'roll
Вот набросал основное,но проблема в том что не происходит возврат в каталог на уровень вверх.Опыта отладки таких объемов недостает.Может кто заметит откровенные ляпы.Заранее благодарен.
[HTML].model small
.stack 100h
.data
startmsg db 'Ierarhiya katalogov diska: $'
nocatmsg db 'Katalogov ne naideno $'
root db 'c:\',0
space db ' $'
crlf db 13,10,'$'
symb db 10h
fmask db '*',0h
bufDTA db 80 dup (0)
FindCatP dw 0
PreCatP dw 0
.code
SearchInto proc ;процедура поиска в найденном ранее каталоге
mov al,[si]
cmp al,2eh ;не является ли . или .. именем
je SIex ;если да - на конец
mov ah,09h
mov dx,offset crlf
int 21h ;перевод строки
mov ah,09h
mov dx,offset space
int 21h ;вывод отступа
mov ax,FindCatP
mov PreCatP,ax ;сохрание каталога возврата
mov ah,3bh
mov dx,FindCatP
int 21h ;chdir на найденный каталог
mov ah,4eh
mov cx,10h
lea dx,fmask
int 21h ;поиск каталога
cmp ax,12h ;проверка есть ли каталоги - нету то на выход
je SIex
mov si,offset bufDTA + 30 ;в si смещение имени найденного каталога
mov FindCatP,si ;имя найденного каталога
call DirNameOut ;вызов вывода имени
call SearchDir ;вызов дальнейшего поиска
SIex: push bp ;передача через стек имени катлога возврата
mov bp,sp ;оно помещалось в стек до вызова
mov ax,[bp + 6]
mov PreCatp,ax
mov ah,3bh
mov dx,PreCatP
int 21h ;chdir на предыдущий каталог
pop bp ;восстановление bp
ret
endp
SearchDir proc ;процедура дальнейшего поиска
mov cx,100 ;сколько раз будет искать
SDser: mov ah,4fh
int 21h ;поиск по параметрам вызова 4eh
cmp ax,18 ;если нет больше файлов то в ах 18
je SDexit
mov si,offset bufDTA + 30 ;в si смещение имени найденного каталога
mov FindCatP,si ;сохранение имени найденного каталога
call DirNameOut ;вызов вывода имени
mov si,FindCatP
mov ax,PreCatp
push ax ;сохранение каталога в который нырнули
call SearchInto ;вызов поиска внутри найденного каталога
loop SDser
SDexit: ret
endp
DirNameOut proc ;процедура вывода имени
mov bx,FindCatP
mov al,[bx]
cmp al,2eh ;не является ли . или .. именем
je DNOexit
mov ah,09h
mov dx,offset crlf
int 21h ;пеервод строки
mov ah,02h
mov bx,offset symb
mov dl,[bx]
int 21h ;вывод посимвольно
nmout: mov dl,[si]
cmp dl,0
je DNOexit
mov ah,02h
int 21h
inc si
jmp nmout
DNOexit: ret
endp
Go:
mov ax,@data
mov ds,ax
mov es,ax ;установка DS и ES
mov ah,1ah
mov dx,offset bufDTA
int 21h ;установка адреса DTA
mov ah,09h
mov dx,offset startmsg
int 21h ;стартовое сообщение
;mov ah,3bh
;mov dx,offset root
;int 21h ;переход в корeнь
mov ah,4eh
mov cx,10h
lea dx,fmask
int 21h ;поиск каталога
cmp ax,12h ;проверка есть ли каталоги
jne Fcat
mov ah,09h
mov dx,offset crlf
int 21h ;пеервод строки
mov ah,09h
mov dx,offset nocatmsg
int 21h
jmp Mex ;если нет вывод сообщения,иначе продолжение
Fcat: mov si,offset bufDTA + 30 ;в si смещение имени найденного каталога
mov FindCatP,si ;сохранение имени найденного каталога
mov PreCatp,si
call DirNameOut ;вызов вывода имени
mov ax,PreCatp
push ax ;сохранение каталога в который нырнули
call SearchInto ;поиск внутри найденного
call SearchDir ;поиск дальше
Mex: mov ah,4ch ;выход в ДОС
int 21h
end Go[/HTML]
[HTML].model small
.stack 100h
.data
startmsg db 'Ierarhiya katalogov diska: $'
nocatmsg db 'Katalogov ne naideno $'
root db 'c:\',0
space db ' $'
crlf db 13,10,'$'
symb db 10h
fmask db '*',0h
bufDTA db 80 dup (0)
FindCatP dw 0
PreCatP dw 0
.code
SearchInto proc ;процедура поиска в найденном ранее каталоге
mov al,[si]
cmp al,2eh ;не является ли . или .. именем
je SIex ;если да - на конец
mov ah,09h
mov dx,offset crlf
int 21h ;перевод строки
mov ah,09h
mov dx,offset space
int 21h ;вывод отступа
mov ax,FindCatP
mov PreCatP,ax ;сохрание каталога возврата
mov ah,3bh
mov dx,FindCatP
int 21h ;chdir на найденный каталог
mov ah,4eh
mov cx,10h
lea dx,fmask
int 21h ;поиск каталога
cmp ax,12h ;проверка есть ли каталоги - нету то на выход
je SIex
mov si,offset bufDTA + 30 ;в si смещение имени найденного каталога
mov FindCatP,si ;имя найденного каталога
call DirNameOut ;вызов вывода имени
call SearchDir ;вызов дальнейшего поиска
SIex: push bp ;передача через стек имени катлога возврата
mov bp,sp ;оно помещалось в стек до вызова
mov ax,[bp + 6]
mov PreCatp,ax
mov ah,3bh
mov dx,PreCatP
int 21h ;chdir на предыдущий каталог
pop bp ;восстановление bp
ret
endp
SearchDir proc ;процедура дальнейшего поиска
mov cx,100 ;сколько раз будет искать
SDser: mov ah,4fh
int 21h ;поиск по параметрам вызова 4eh
cmp ax,18 ;если нет больше файлов то в ах 18
je SDexit
mov si,offset bufDTA + 30 ;в si смещение имени найденного каталога
mov FindCatP,si ;сохранение имени найденного каталога
call DirNameOut ;вызов вывода имени
mov si,FindCatP
mov ax,PreCatp
push ax ;сохранение каталога в который нырнули
call SearchInto ;вызов поиска внутри найденного каталога
loop SDser
SDexit: ret
endp
DirNameOut proc ;процедура вывода имени
mov bx,FindCatP
mov al,[bx]
cmp al,2eh ;не является ли . или .. именем
je DNOexit
mov ah,09h
mov dx,offset crlf
int 21h ;пеервод строки
mov ah,02h
mov bx,offset symb
mov dl,[bx]
int 21h ;вывод посимвольно
nmout: mov dl,[si]
cmp dl,0
je DNOexit
mov ah,02h
int 21h
inc si
jmp nmout
DNOexit: ret
endp
Go:
mov ax,@data
mov ds,ax
mov es,ax ;установка DS и ES
mov ah,1ah
mov dx,offset bufDTA
int 21h ;установка адреса DTA
mov ah,09h
mov dx,offset startmsg
int 21h ;стартовое сообщение
;mov ah,3bh
;mov dx,offset root
;int 21h ;переход в корeнь
mov ah,4eh
mov cx,10h
lea dx,fmask
int 21h ;поиск каталога
cmp ax,12h ;проверка есть ли каталоги
jne Fcat
mov ah,09h
mov dx,offset crlf
int 21h ;пеервод строки
mov ah,09h
mov dx,offset nocatmsg
int 21h
jmp Mex ;если нет вывод сообщения,иначе продолжение
Fcat: mov si,offset bufDTA + 30 ;в si смещение имени найденного каталога
mov FindCatP,si ;сохранение имени найденного каталога
mov PreCatp,si
call DirNameOut ;вызов вывода имени
mov ax,PreCatp
push ax ;сохранение каталога в который нырнули
call SearchInto ;поиск внутри найденного
call SearchDir ;поиск дальше
Mex: mov ah,4ch ;выход в ДОС
int 21h
end Go[/HTML]
Написал основное - но проблема в том что не работает дальнейший поиск(результат 4fh int 21h - нет больше каталогов,хотя они есть).Может кто заметит ошибку.
Код: Выделить всё
.model small
.stack 500h
.data
path db 'c:',0;сюда помещется текущий путь - прибавлять и занулять при переходах
bufarea db 255 dup (0)
startmsg db 'ATTENTION! For correct work use original DOS or the emulator!',13,10,'Hierarchy of catalogues of a disk: $'
nocatmsg db 'Catalogues are not found $'
IPback dw 0
rekidx db 0
crlf db 13,10,'$'
symb db 10h
fmask db '*',0h
bufDTA db 80 dup (0)
FCatNm db 8 dup (0)
FCatNmP dw 0
.code
SearchInto proc ;рекурсивная процедура поиска-заходит в найденный ранее
;каталог - ищет в нем - на каждый найденный вызывает себя
call AddPath ;формированеи пути для захода в каталог
mov ah,3bh
lea dx,path
int 21h ;chdir на найденный каталог
mov ah,4eh
mov cx,10h
lea dx,fmask
int 21h ;поиск каталога - первым найден .
mov ah,4fh
int 21h ;след найденный ..
mov ah,4fh
int 21h ;есть ли каталоги
cmp ax,0018
je SIex
mov si,offset bufDTA + 30 ;в si смещение имени найденного каталога
mov FCatNmP,si
call SearcInto ;рекурсивный вызов
mov cx,100 ;поиск файлов 100 раз
SI4fh: mov ah,4fh
int 21h
cmp ax,0018 ;если найдено в ах 18
je SIex
mov si,offset bufDTA + 30 ;в si смещение имени найденного каталога
mov FCatNmP,si
call DirNameOut ;вывод имени найденного каталога
call SearchInto ;поиск в нем
loop SI4fh
Siex:
call SubPath ;формированеи пути для выхода из каталога
mov ah,3bh
lea dx,path
int 21h ;chdir на каталог откуда вызов
ret
endp
DirNameOut proc
mov ah,09h
mov dx,offset crlf
int 21hcall ;перевод строки
mov ah,02h
mov bx,offset symb
mov dl,[bx]
int 21h ;вывод символа >
nmout: mov dl,[si]
cmp dl,0
je DNOexit
mov ah,02h
int 21h ;посимвольный вывод
inc si
jmp nmout
DNOexit: ret
endp
AddPath proc
inc rekidx
mov si,FCatNmP
lea di,path
PEndng: mov bl,[di] ;переход на конец строки пути
cmp bl,0
je PEnd1
inc di
jmp PEndng
PEnd1:
mov al,92
mov [di],al ;\ в конец пути
inc di
mov cx,8
PEnd2: mov bl,[si]
cmp bl,0
je APend
repnz movsb ;прибавление к пути строки имени найденного каталога
APend:
ret
endp
SubPath proc
dec rekidx
lea di,path
PEndg: mov bl,[di] ;переход на конец строки пути
cmp bl,0
je PaEnd
inc di
jmp PEndg
PaEnd:
;по строке пути к началу
mov al,0 ;зануляя до \
mov bl,[di]
cmp bl,'\'
je BackP
mov [di],al
dec di
jmp PaEnd
BackP:
ret
endp
SaveIndx proc ;процедура помещения в стек индекса поиска
pop ax
mov IPback,ax ;сохранение точки возврата
mov bx,offset bufDTA + 20 ;смещение конца индекса
mov cx,20 ;под индекс дос отводит 20 байт
Pual: xor ax,ax
mov al,[bx] ;содержимое байта в al
push ax ;сохранение в стеке
dec bx ;переход на байт младше
loop Pual ;повтор
xor ax,ax ;восстановление точки возврата
mov ax,IPback
push ax
ret
endp
LoadIndx proc ;процедура изъятия из стека индекса поиска
pop ax
mov IPback,ax ;сохранение точки возврата
mov cx,20 ;под индекс 20 байт
mov bx,offset bufDTA ;смещение начала индекса
Poal: xor ax,ax
pop ax ;из стека в ал
mov [bx],al ;содержимое байта в память
inc bx ;след байт индекса
loop Poal ;повтор
xor ax,ax
mov ax,IPback
push ax ;восстановление точки возврата
ret
endp
Go:
mov ax,@data
mov ds,ax
mov es,ax ;установка DS и ES
mov ah,1ah
mov dx,offset bufDTA
int 21h ;установка адреса DTA
mov ah,09h
mov dx,offset startmsg
int 21h
mov ah,4eh
mov cx,10h
lea dx,fmask
int 21h ;поиск каталога
cmp ax,12h ;проверка есть ли каталоги
jne Fcat
mov ah,09h
mov dx,offset crlf
int 21h ;пеервод строки
mov ah,09h
mov dx,offset nocatmsg
int 21h
jmp Mex ;если нет вывод сообщения,иначе продолжение
Fcat: mov si,offset bufDTA + 30 ;в si смещение имени найденного каталога
mov FCatNmP,si
mov bx,FCatNmP
mov al,[bx]
cmp al,2eh ;не является ли . или .. именем
je Mex
call SaveIndx ;сохранение индекса для дальнейшего поиска
call SearchInto ;поиск в найденном
call LoadIndx ;восстановления индекса
M4fh: mov ah,4fh
int 21h
cmp ax,0018 ;найдены ли каталоги
je Mex
mov si,offset bufDTA + 30 ;в si смещение имени найденного каталога
mov FCatNmP,si
call SearchInto ;поиск в найденном каталоге
loop M4fh
Mex: mov ah,4ch ;выход в ДОС
int 21h
end Go