;Ввести с клавиатуры имя каталога и маску файлов. Перенести
;все соответствующие маске файлы в каталог уровнем выше указанного.
;Если указанный каталог остался пуст – удалить его.
.model tiny
.code
.startup
call GetMask ;вводим путь и маску, разбираем их
jc finish ; вводить надо обязательно с '\'
; хотя бы? так: ".\*.*"
call MoveFiles ;перемещаем файлы
call DelDir ;если каталог пустой, то удаляем
finish:
mov ax, 4c00h
int 21h
GetMask proc ;вводим путь с маской
lea dx, prompt ;подсказка
mov ah, 9
int 21h
lea dx, max ;вводим путь и маску
mov ah, 0ah
int 21h
xor bx, bx
mov bl, len
mov string[bx], 0 ;заменим 0dh на 0
GMParseLoop: ;ищем последний '\'
test bx, bx ;дошли до начала, '\' не нашли
jz GMError
cmp string[bx-1], ':' ; аналогично, только дошли до диска
je GMError
cmp string[bx-1], '\' ;нашли '\'
je GMFound
dec bx ;идем к началу
jmp GMParseLoop
GMFound: ;нашли последний '\'
lea di, path ;копируем сюда, как путь директории выше
lea si, string ;введенный путь
mov cx, bx ;длина до '\' включительно
rep movsb ;копируем
mov word ptr [di], '..' ;добавим '..' для указания на путь выше
mov word ptr [di+2], '\' ;добавим разделитель, сюда будем добавлять имя файла
lea ax, [di+3] ;позиция имени файла
mov pNameNew, ax ;сохраняем
lea di, fpath ;путь до исходных файлов
lea si, string ;введенный путь
mov cx, bx
rep movsb ;копируем
mov pNameOld, di ;сохраняем позицию имени файла
clc ;все ок
ret
GMError:
lea dx, pParmError ;сообщение об ошибке
mov ah, 9
int 21h
stc
ret
GetMask endp
MoveFiles proc ;перемещаем файлы
lea dx, dta
mov ah, 1ah
int 21h ;устанавливаем свою область DTA
mov cx, 0 ;аттрибут - только файлы
mov ah, 4eh ;ищем первого
SearchLoop:
lea dx, string ;путь с маской
int 21h
jc NoFiles ;не найдено - уходим
mov di, pNameOld ;позиция в исходном пути, куда вставить имя файла
mov bx, pNameNew ;позиция в результирующем пути, куда вставить имя файла
lea si, dta.fname ;адрес имени файла в DTA
formFPath:
lodsb ;копируем имя файла
stosb ;в оба буфера
mov [bx], al
inc bx
cmp al, 0 ;вместе с последним 0
jne formFPath
lea dx, fpath ;ds:dx - путь с исходным именем
lea di, path ;es:di - путь с именем, куда перенесем
mov ah, 56h
int 21h ;move
;выведем имя файла на экран
mov al, 0dh ;перевод строки
int 29h
mov al, 0ah
int 29h
lea si, dta.fname ;имя файла
MFPrint:
lodsb
cmp al, 0
je MFNext
int 29h
jmp MFPrint
MFNext:
mov ah, 4fh ;продолжение поиска
jmp SearchLoop ;ищем дальше
NoFiles:
ret
MoveFiles endp
DelDir proc ;удаляем каталог
;проверим, совпадает ли текущий каталог с заданным
;для этого сначала определим диск
lea si, string ;сюда запишем текущий путь (он будет без диска)
lea di, fpath ;строка с путем
mov dl, 0 ;устройство по-умолчанию, если не диск не задан
cmp byte ptr [si+1],':' ;проверим на задание диска
jne GetCurrentDir ;не задан - читаем текущий каталог
mov dl, [si] ;первый символ - диск
or dl, 20h ;делаем букву маленькой
sub dl, 60h ;'a'-1,'b'-2,...
lea si, [si+3] ;обойдем 'c:\'
lea di, [di+3]
GetCurrentDir:
mov ah, 47h ;узнаем текущий каталог
int 21h
cmpPaths: ;сравним, причем без учета на большие, маленькие
lodsb
xor al, [di] ;для одинаковых или 0, или 20h
jz Equal
cmp al, 20h
jnz notEqual ;сравниваем, пока не найдем отличие
Equal:
inc di
jmp cmpPaths
notEqual:
cmp byte ptr [si-1], 0 ;пути отличаются
jne ToDelete ;на удаление пути
cmp byte ptr [di], '\' ;пути равны и в этом случае, т.к. дальше имя файла
jne ToDelete
lea dx, path ;равное - перейдем на уровень выше
mov bx, pNameNew
mov byte ptr [bx-1],0 ;закроем путь 0 в позиции '\'
mov ah, 3bh
int 21h ;cd ..
ToDelete:
lea dx, fpath ;исходный путь
mov bx, pNameOld ;позиция пследней '\'
mov byte ptr [bx-1],0 ;закроем путь 0 в позиции '\'
mov ah, 3ah
int 21h ;удаляем исходный каталог
ret
DelDir endp
.data
pParmError db 0dh,0ah,'Enter subdirectory and files mask$'
prompt db 'Enter path and mask: $'
max db 129 ;для ввода пути с маской
len db 0
.data?
string db 129 dup (?) ;здесь будет введенная строка, путь с маской
path db 129 dup (?) ;путь, куда переносим (с ..)
fpath db 129 dup (?) ;исходный путь с именем файла
pNameOld dw ? ;позиция в fpath, куда пишем имя файла
pNameNew dw ? ;позиция в path, куда пишем имя файла
DTAdata struc ;DTA для поиска
reserve db 21 dup (?)
attr db ?
time dw ?
date dw ?
fsize dw ?, ?
fname db 13 dup (?)
DTAdata ends
dta DTAdata <>
end
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.