Програми – аналоги DOS-програм ren, xcopy
Міністерство освіти та науки України
Кіровоградський Державний Технічний університет
Кафедра програмного забезпечення
Курсова робота
з дисципліни “Програмування на мові ASM-86” на тему:
Програми – аналоги DOS-програм ren, xcopy
Зміст
Вступ
Постановка задачі
Обґрунтування вибору методів розв’язку задачі
Алгоритм програми
Реалізація програми
Системні вимоги
Інструкція для користувача
Висновки.
Використана література
Лістинг програми
1. Вступ
З файлами на диску можна проводити певні операції – зокрема перейменовувати та копіювати. У даній роботі розглянуті програми, які дозволяють перейменувати файл і скопіювати задані файли та каталоги. Програми написані на мові ASM-86.
2. Постановка задачі
Необхідно написати програми для перейменування файлів та копіювання файлів і підкаталогів (аналоги REN, XCOPY).
3. Обґрунтування вибору методів розв’язку задачі
Для роботи з файлами в можна використовувати його системний сервіс, який зосереджено в перериванні 21h. Зокрема, використовуються такі функції:
56h – перейменувати файл
3ch – створити файл
3dh – відкрити файл
3eh – закрити файл
40h – читати з файла блок
41h – записати блок у файл
Для перегляду дерева підкаталогів зручно використовувати рекурсивну функцію, яку викликати при вході в підкаталог. Для пошуку будемо використовувати функції 4eh (findfirst) I 4fh (findnext).
4. Алгоритм програми
Алгоритм перейменування файла
1. Занести в пам’ять комадний рядок
2. Викликати функцію 56h
3. Якщо була помилка, то вивести повідомлення.
Алгоритм копіювання файлів
1. Проаналізувати командний рядок
2. Знайти всі файли в поточному каталозі, які відповідають заданій масці
3. Для кожного файла викликати функцію copy_file
4. Якщо не було задано ключ /s, то закінчити перегляд
5. Знайти всі підкаталоги
6. Зайти в кожен підкаталог диску і рекурсивно перейти в п. 2.
7. При завершенні повернутися у вихідний каталог
8. Кінець
5. Реалізація програми
Програма складається з функцій. Після запуску програми викликається функція process_commandline для аналізу командного рядка. Потім відбувається виклик функції process_files, яка копіює всі файли в заданому каталозі в заданий. Копіювання здійснюється за допомогою функції copy_file.
Якщо було задано параметр копіювання підкаталогів, викликається функція process_directory, яка шукає всі підкаталоги в даному і для кожного рекурсивно викликає функцію process_files.
Після обробки всіх файлів і каталогів виконання програми завершується. При копіюванні файлів виводиться ім’я кожного.
6. Системні вимоги
Операційна система DOS
CPU INTEL 8086 або ст.
RAM 640 K
VIDEO CGA або старший
7. Інструкція для користувача
Для використання програми перейменування файлів треба вказати:
k_ren letter.doc letter.txt
Якщо не виникне помилок, то файл буде перейменовано.
Для копіювання треба вказати такий рядок:
k_xcopy *.com c:\utils [/s]
де *.com – маска для файлів, які треба копіювати, c:\utils – каталог, куди треба копіювати, а необов’язковий ключ /s вказує на те, що в копіювання треба включити також підкаталоги даного підкаталогу. При копіюванні буде створено точну копію частини дерева.
8. Висновки
Завдяки виконанню курсового проекту створені програми для перейменування файлів та копіювання групи файлів. Вони є прикладом роботи з файловою системою засобами MS-DOS і демонструє елементи системного програмування для IBM PC.
9. Використана література
1. Майко Г. В. Assembler для IBM PC. М., 1997
2. Лекції з дисципліни “Програмування на мові ASM-86”
Додаток. ЛІСТИНГ ПРОГРАМИ
K_XCOPY.ASM
.model tiny
.code
org 100h
start:
jmp begin
mem_errmsg db 'Memory allocation error.$'
file_errmsg db 'Files error!$'
param_err db 'Parameters error! Example: k_xcopy c:\*.* d: [/s]$'
all_dirs db '*.*',0
up_dir db '..',0
handle_1 dw 0
handle_2 dw 0
orig_date dw 0
orig_time dw 0
process_dirs db 0 ;вкл. пiдкаталоги
filename_1 db 100 dup(0) ;1 параметр _xcopy
filename_2 db 100 dup(0) ;2 параметр _xcopy
targetname db 100 dup(0) ;сюди буде формуватися iм`я файла призначення
;;;;;;;;;;;;;;;;
;копiювання файла
;ds:si - ASCIIZ старий файл
;ds:di - ASCIIZ новий файл
;;;;;;;;;;;;;;;;
copy_file proc
;видiлити пам`ять
mov ah,48h
mov bx,2048
int 21h
jnc mem_ok
jmp mem_err
mem_ok:
mov es,ax ;сегмент видiлений для копiювання
;open file for read
mov ah,3dh
xor al,al
mov dx,si
int 21h
jc file_error
mov word ptr handle_1,ax
;get date
mov bx,ax
mov ax,5700h
int 21h
mov word ptr orig_time,cx
mov word ptr orig_date,dx
;open file for write
mov ah,3ch
xor cx,cx
mov dx,di
int 21h
jc file_error
mov word ptr handle_2,ax
push ds
push es
pop ds
xor dx,dx
;read block
next_block:
mov ah,3fh
mov bx,word ptr cs:handle_1
mov cx,32768
int 21h
cmp ax,0 ;eof
je stop_copy
;write to file
mov cx,ax
mov ah,40h
mov bx,word ptr cs:handle_2
int 21h
jmp next_block
stop_copy:
pop ds
;set date
mov ax,5701h
mov bx,word ptr handle_2
mov cx,word ptr orig_time
mov dx,word ptr orig_date
int 21h
;close files
mov ah,3eh
mov bx,word ptr handle_1
int 21h
mov ah,3eh
mov bx,word ptr handle_2
int 21h
;attrib
mov ah,43h
xor al,al
mov dx,offset filename_1
int 21h
mov ah,43h
mov al,1
mov dx,offset filename_2
int 21h
;звiльнити
mov ah,49h
int 21h
jc mem_err
ret
file_error:
mov ah,9
mov dx,offset file_errmsg
int 21h
mov ah,4ch
int 21h
mem_err:
mov ah,9
mov dx,offset mem_errmsg
int 21h
mov ah,4ch
int 21h
copy_file endp
;;;;;;;;;
;end copy_file
;;;;;;;;;
;;;;;;;;;;
;process_dirs
;;;;;;;;;;
process_directory proc
;взнати адресу DTA
mov ah,2fh
int 21h ;es:bx - DTA
;findfirst
mov ah,4eh
mov cx,10h
mov dx,offset all_dirs ;*.*
int 21h
dfindnext:
jnc zzz
jmp dstop_search ;кiнець пошуку
zzz:
cmp byte ptr [bx+15h],10h
jne not_dir
cmp byte ptr [bx+1eh],'.'
je not_dir
;отже,знайдено пiдкаталог
;1) до filename_2 додати його назву
mov di,offset filename_2
mov cx,100
xor ax,ax
repnz scasb
dec di
mov si,bx
add si,1eh
mov cx,13
rep movsb
;2) створити каталог filename_2
mov ah,39h
mov dx,offset filename_2
int 21h
;3) до filename_2 додати \
mov di,offset filename_2
mov cx,100
xor ax,ax
repnz scasb
dec di
mov byte ptr [di],'\'
mov byte ptr [di+1],0
push di
;4) перейти в знайдений каталог
mov ah,3bh
mov dx,bx
add dx,1eh
int 21h
jc skip_thisd
;5) зберегти DTA
sub> sp,2bh
cld
mov di,sp
mov si,bx
mov cx,2bh
rep movsb
;6) call process_files
call process_files
;7) вiдновити DTA
mov di,bx
mov si,sp
mov cx,2bh
rep movsb
add sp,2bh
;8) chdir ..
mov ah,3bh
mov dx,offset up_dir
int 21h
skip_thisd:
;9) вiд filename_2 вiдняти назву
pop di
sub> di,2
std
mov al,'\'
mov cx,13
repnz scasb
mov byte ptr [di+2],0
cld
not_dir:
;робимо findnext
mov ah,4fh
int 21h
jmp dfindnext
dstop_search: ;стоп пошуку
ret
process_directory endp
;;;;;;;;;;;;
;process_dirs
;;;;;;;;;;;;
;;;;;;;;
;process_files
;;;;;;;;
;копiювання файлiв в 1 каталозi
process_files proc
;взнати адресу DTA
mov ah,2fh
int 21h ;es:bx - DTA
;findfirst
mov ah,4eh
xor cx,cx
mov dx,offset filename_1
int 21h
findnext:
jc stop_search ;кiнець пошуку
;;copy
;побудувати targetname
push es
;копiюємо path
mov si,offset filename_2
mov di,offset targetname
push ds
pop es
fil0: lodsb
cmp al,0
je stop_fil0
stosb
loop fil0
stop_fil0:
;додати filename
mov si,bx
add si,1eh
fil1:
lodsb
cmp al,0
je stop_fil1
stosb
loop fil1
stop_fil1:
mov byte ptr [di],0
mov si,bx
add si,1eh
mov di,offset targetname
push bx
call copy_file
pop bx
pop es
;видати iм`я файла
mov si,bx
add si,1eh
cont_inc:
mov al,[si]
cmp al,0
je stop_inc
inc si
jmp cont_inc
stop_inc:
mov byte ptr [si],10
mov byte ptr [si+1],13
mov byte ptr [si+2],'$'
mov dx,bx
add dx,1eh
mov ah,9
int 21h
;;copy
;робимо findnext
mov ah,4fh
int 21h
jmp findnext
stop_search: ;стоп пошуку
cmp byte ptr ds:[process_dirs],1
jne no_dirs
;
;виклик пошуку каталогiв
;
call process_directory
no_dirs:
ret
process_files endp
;;;;;;;;
;process_files
;;;;;;;;
;;;;;;;;
;process_commandline
;;;;;;;;
process_commandline proc
mov si,80h
mov al,[si]
cmp al,0
je params_error
add si,2
mov di,offset filename_1
name_1:
lodsb
cmp al,20h
je stop_name1
cmp al,13
je params_error
stosb
jmp name_1
stop_name1:
mov di,offset filename_2
name_2:
lodsb
cmp al,20h
je stop_name2
cmp al,13
je stop_name2
stosb
jmp name_2
stop_name2:
mov byte ptr [di],'\'
cmp al,13
je stop_cmdl
name_s:
lodsb
cmp al,20h
je stop_names
cmp al,13
je stop_names
cmp al,'s'
jne name_s
mov byte ptr [process_dirs],1
stop_names:
stop_cmdl:
ret
params_error:
mov dx,offset param_err
mov ah,9
int 21h
mov ah,4ch
int 21h
process_commandline endp
;;;;;;;;
;process_commandline
;;;;;;;;
begin:
;decrease memory size
cld
mov bx,4096
mov ah,4ah
int 21h
mov ax,bx
shl ax,4
dec ax
mov sp,ax
call process_commandline
call process_files
.exit 0
end start
K_REN.ASM
;перейменування файла
;k_ren name1.ext1 name2.ext2
.model tiny
.code
org 100h
start:
jmp go
old_name db 50 dup(0)
new_name db 50 dup(0)
;old_name db 'autoexec.bat',0
;new_name db 'ccc.xxx',0
em db 'Error!$'
go:
push cs
pop ax
mov ds,ax
mov es,ax
;names
mov bx,80h
mov dl,byte ptr cs:[bx] ;length
cmp dl,0
je error
;old name
xor ax,ax
mov si,82h
mov di,offset old_name
next_sym:
mov al,[si]
cmp al,' '
je stop
mov [di],al
inc si
inc di
inc ah
cmp ah,dl
ja error
jmp next_sym
stop:
;new name
mov di,offset new_name
inc si
next_sym1:
mov al,[si]
cmp al,13
je stop1
mov [di],al
inc si
inc di
inc ah
cmp ah,dl
ja error
jmp next_sym1
stop1:
;перейменовуємо
mov dx, offset old_name
mov di, offset new_name
mov ah,56h
int 21h
jnc no_error
error:
mov ah,9
mov dx,offset em
int 21h
no_error:
.exit 0
end start