< -->
;fchss.asm
;Заменяет в файле строку на строку из такого же количества символов
.model tiny
.code
.386
org 100h
FREAD equ 0F800h ;32768 байт
start:
mov al, 254
mov byte ptr strbufflen, al
mov byte ptr strbufflen_, al
mov byte ptr _strbufflen, al
mov dx, offset message
mov ah, 9
int 21h
mov dx, offset _strbufflen
mov ah, 0Ah
int 21h
mov dx, offset EOL
mov ah, 9
int 21h
xor bx, bx
mov bl, byte ptr _strlen
mov byte ptr _strbuff[bx], 0
mov ax, 3D23h ;Открыть файл: чтение/запись/
;все операции для других процессов запрещены
mov dx, offset _strbuff
mov cl, 00100111b;атрибуты - арх, сист, скрыт, тдч
int 21h
jc error_exit
mov idfile, ax
mov dx, offset mess1
mov ah, 9
int 21h
mov dx, offset strbufflen
mov ah, 0Ah
int 21h
mov dx, offset EOL
mov ah, 9
int 21h
mov dx, offset mess2
mov ah, 9
int 21h
mov dx, offset strbufflen_
mov ah, 0Ah
int 21h
mov dx, offset EOL
mov ah, 9
int 21h
xor ax, ax
mov al, strlen
test al, al
jnz next_check
push ax
mov ah, 9
mov dx, offset error_lsz
int 21h
pop ax
inc ah
next_check:
cmp al, byte ptr strlen_
je processing
mov ah, 9
mov dx, offset error_nes
int 21h
jmp closefilenexit
processing:
test ah, ah
jnz closefilenexit
mov ax, 5B10h
;все операции для других процессов запрещены
mov dx, offset tmpfile
mov cx, 0000000000100000b;атрибуты - арх
int 21h
mov tmpidfile, ax
mov ax, 4200h
xor cx, cx
xor dx, dx
mov dl, strlen
mov bx, idfile
int 21h
read_loop:
mov ax, 4201h
xor cx, cx
xor dx, dx
mov cl, strlen
sub dx, cx
mov cx, 0FFFFh
mov bx, idfile
int 21h
mov ah, 3Fh ;читаем файл
mov bx, idfile
mov cx, FREAD
mov dx, offset filebuffer
int 21h
jc closeallnexit
mov flen, ax
push ax
call findings
call writetmp
pop ax
cmp ax, FREAD
je read_loop
closeallnexit:
mov bx, tmpidfile
mov ah, 3Eh
int 21h
mov bx, idfile ;закрываем файлы
mov ah, 3Eh
int 21h
;удаляем старый
mov ah, 41h
mov dx, offset _strbuff
int 21h
;переименовываем tmp в old
mov ah, 56h
mov dx, offset tmpfile ;старое имя
mov di, offset _strbuff ;новое имя
int 21h
jmp short exit_prog
closefilenexit:
mov bx, idfile ;закрываем файл
mov ah, 3Eh
int 21h
jmp short exit_prog
error_exit:
push ax
mov dx, offset error_msg
mov ah, 9
int 21h
pop ax
mov dx, offset error_fnf
cmp ax, 02h
je pne
mov dx, offset error_pnf
cmp ax, 03h
je pne
mov dx, offset error_ftm
cmp ax, 04h
je pne
mov dx, offset error_acd
cmp ax, 05h
je pne
mov dx, offset error_uid
cmp ax, 06h
je pne
mov dx, offset error_bam
cmp ax, 0Ch
je pne
mov dx, offset EOL
pne:
mov ah, 9
int 21h
exit_prog:
ret
findings proc near ; Процедура ищет подстроку в строке
;(все её вхождения) и заменяет её на другую строку
mov di, offset filebuffer ;буфер с содержимым файла
dec di ;потом увеличится на 1
push di
xor cx, cx
cld ;флаг направления
new_iter:
pop di ;смещаемся в буфере для сравнения с искомой строкой
inc di ;со следующего байта
mov si, offset strbuff ;искомая строка
push di ;сохраняем для последующего использования
mov cl, strlen ;длина подстроки, возвращается ещё DOS
repe cmpsb ;сравниваем до первого различия
jcxz copy_str ;если вся длина строки вышла - переходим
;на процедуру копирования
;{неэффективен при строках длиной 1 и 2 байта, т.к. cx
;становится равным 0}
lbd: ;лабуда...
sub di, offset filebuffer ;это конец буфера, или нет?
cmp di, flen
jne new_iter ;нет - сравниваем дальше
jmp short exit_procedure ;иначе - выходим
copy_str:
jne short lbd ;если после сравнивания последние байты
;не равны - то выходим
;из подпрограммы копирования
push si ;сохранить - изменится
mov cl, strlen ;длина копируемой строки
sub di, cx ;положение в буфере для заменяемой строки
mov si, offset strbuff_ ;смещение копируемой строки
rep movsb ;копируем
pop si ;восстанавливаем регистр
jmp short lbd
exit_procedure: ;выходим, извлекая из стека ненужное слово
pop di ;оставшееся там после сохранения di
ret
findings endp
writetmp proc near
mov ah, 40h
mov bx, tmpidfile
mov cx, flen
mov dx, offset filebuffer
int 21h
mov ax, 4201h
xor cx, cx
xor dx, dx
mov cl, strlen
sub dx, cx
mov cx, 0FFFFh
mov bx, tmpidfile
int 21h
ret
writetmp endp
tmpfile db "fchs.tmp", 0
message db "Введите имя файла: ","$"
mess1 db "Введите строку для поиска: ","$"
mess2 db "Введите строку для замены: ","$"
error_msg db "Ошибка при открытии файла: ", "$"
error_fnf db "Файл не найден",0Ah, 0Dh, "$"
error_pnf db "Путь не найден",0Ah, 0Dh, "$"
error_ftm db "Слишком много открытых файлов",0Ah, 0Dh, "$"
error_acd db "Доступ запрещён",0Ah, 0Dh, "$"
error_bam db "Неправильный режим доступа",0Ah, 0Dh, "$"
error_uid db "Неправильный идентификатор файла",0Ah, 0Dh, "$"
error_frw db "Ошибка чтения/записи из/в файл(а)", 0Ah, 0Dh, "$"
error_nes db "Строки различны по длине!", 0Ah, 0Dh, "$"
error_lsz db "Строка для поиска пуста!"
EOL db 0Ah, 0Dh, "$"
flen dw ?
idfile dw ?
tmpidfile dw ?
_strbufflen db ?
_strlen db ?
_strbuff db 254 dup (?)
strbufflen db ?
strlen db ?
strbuff db 254 dup (?)
strbufflen_ db ?
strlen_ db ?
strbuff_ db 254 dup (?)
filebuffer:
end start
Назад