Консультация № 178551
21.05.2010, 18:06
43.11 руб.
0 1 1
Уважаемые эксперты! Требуется написать программу(с комментариями) Ввести с клавиатуры имя каталога и маску файлов. Перенести все соответствующие маске файлы в каталог уровнем выше указанного. Если указанный каталог остался пуст – удалить его. Работа с диском средствами DOS и BIOS. Внимание! Все работы выполняются в DOSBox (VirtualPC) с образом дискеты, иначе можно испортить данные на винчестере.(Это так маленький комментарий)) Буду очень признателен если сделаете программу.
Платформа DOS, ассемблер TASM.

Обсуждение

давно
Посетитель
7438
7205
24.05.2010, 02:28
общий
это ответ
Здравствуйте, Филимонов Алексей Викторович.
Программа ниже.
При вводе ждет полный путь вместе с маской...
Код:
;Ввести с клавиатуры имя каталога и маску файлов. Перенести 
;все соответствующие маске файлы в каталог уровнем выше указанного.
;Если указанный каталог остался пуст – удалить его.
.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
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа