Добавил:
alexa_ak
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:лабы / 9
.txt .model small
.data
BUFSIZE equ 200 ; константы задать с помощью директивы EQU;
msg0 db 13,10,'Input set of letters: $'
msg3 db 13,10,'Input new word: $'
msg1 db 13,10,'Input text. Empty string - finish:',13,10,'$'
msg2 db 13,10,'Result: $'
set db BUFSIZE,BUFSIZE+1 dup(0) ;выделить буфер для хранения 200 символов набора символов
wrd db BUFSIZE,BUFSIZE+1 dup(0) ;выделить буфер для хранения 200 символов другого слова
buf db BUFSIZE,BUFSIZE+1 dup(0) ;выделить буфер для хранения 200 символов строки
.stack 256
.code
start:
mov ax,@data ;Настраиваем сегментные регистры
mov ds,ax
mov es,ax
mov ah,9 ;функция вывода сообщения на экран
lea dx,msg0 ;выводимое сообщение
int 21h ;выводим на экран
mov ah,0ah ;функция ввода строки с клавиатуры
mov dx,offset set ;буфер куда вводить
int 21h ;пользователь вводит в текст в buf
mov ah,9 ;функция вывода сообщения на экран
lea dx,msg3 ;выводимое сообщение
int 21h ;выводим на экран
mov ah,0ah ;функция ввода строки с клавиатуры
mov dx,offset wrd ;буфер куда вводить
int 21h ;пользователь вводит в текст в buf
mov ah,9 ;функция вывода сообщения на экран
lea dx,msg1 ;выводимое сообщение
int 21h ;выводим на экран
mainlp: посимвольный ввод символов
mov ah,0ah ;функция ввода строки с клавиатуры
mov dx,offset buf ;буфер куда вводить
int 21h ;пользователь вводит в текст в buf
cmp buf[1],0 ;если строка не пустая
jnz q1 ;продолжить
jmp ex ;если пустая - выйти, него в ней менять
q1: lea si,buf[2] ;начало строки
lp1: ; поиск начала очередного слова
mov al,[si] ;прочитать очередной символ
cmp al,13 ;если конец строки
jz fin1 ;то закончить
cmp al,' ' ;если не пробел
jnz m1 ;то переход
inc si ;следующий символ
jmp lp1 ;продолжить поиск начала слова
m1: mov dx,si ;запомнить адрес начала слова
lp2:; поиск конца слова
mov al,[si] ;прочитать очередной символ
cmp al,13 ;если конец строки
jz m2 ;то закончить слово
cmp al,' ' ;если пробел
jz m2 ;то закончить слово
inc si ;следующий символ
jmp lp2 ;продолжить поиск конца слова
m2: mov ax,si ;адрес конца слова
sub ax,dx ;вычесть адрес начала, получили длину
lea bx,set[2] ;начало множества символов
mov cl,set[1] ;количество символов в множестве
a2: mov di,dx ;адрес начала слова
mov ch,[bx] ;взять очередную букву из набора
mov bp,ax ;длина слова
a1: cmp ch,[di] ;если очередная буква из набора входит в слово
jz vhodit ;то переход
inc di ;перейти с кледующей букве слова
dec bp ;уменьшить кол-во оставшихся в слове букв
jnz a1 ;продолжить пока не 0
; если дошли сюда, то буква не входит в слово
jmp lp1 ;поиск следующего слова
vhodit: inc bx ;перейти к следующей букве набора
dec cl ;уменьшить кол-во оставшихся в наборе букв
jnz a2 ;продолжить пока не 0
; если дошли сюда, значит все буквы набора есть в слове
mov bx,dx ;адрес начала слова
mov cx,ax ;длина слова
call shift ;удалить слово из строки
sub si,cx ;вычесть из текущего положения в строке длину слова
mov cl,wrd[1] ;длина другого слова
mov ch,0 ;сх=длина другого слова
neg cx ;сх=-длина другого слова
call shift ;вставить место под другое слово
add si,cx ;прибавить к текущему положению в строке длину другого слова
neg cx ;сх=длина другого слова
push si ;сохранить регистр
mov di,dx ;место куда вставлять (начало старого слова)
lea si,wrd[2] ;адрес другого слова
rep movsb ;скопировать другое слово в строку
pop si ;восстановить регистр
jmp lp1 ;поиск следующего слова
fin1:
mov ah,9 ;функция вывода сообщения на экран
lea dx,msg2 ;выводимое сообщение
int 21h ;выводим на экран
lea si,buf[2]
; Вывод строки на экран. Строка должна заканчиваться нулевым байтом
;ds:si - выводимая строка
mov ah,2 ;функция вывода символа на экран
os1: mov dl,[si] ;взять очередной символ из строки
cmp dl,13 ;если это конец строки
jz ose ;то закончить вывод
int 21h ;вывести очередной символ
inc si ;перейти к следующему символу
jmp os1 ;продолжить вывод
ose:
mov dl,13 ;возврат каретки
int 21h ;вывести возврат каретки
mov dl,10 ;перевод строки
int 21h ;вывести перевод строки
jmp mainlp ;продолжить ввод текста
ex: mov ax,4c00h ;закончить программу
int 21h
;сдвиг строки
;ds:bx - адрес сдвигаемой строки
;cx - количество сдвигаемых символов (число со знаком) положительное - сдвиг влево(удаление). Отрицательное - сдвиг вправо(вставка)
shift proc
push si ;сохранить регистры
push di
push cx
push ax
cmp cx,0 ;если ничего сдвигать не нужно
jz no_shift ;то закончить
jl insert ;если кол-во символов сдвига отрицательное, перейти к вставке
;удаление (сдвиг влево)
mov di,bx ;адрес-приемник строки
mov si,di ;адрес-источник строки
add si,cx ;больше приемника на количество сдвигаемых символов
sh1: lodsb ;загрузить символ из источника
stosb ;записать в приемник
cmp al,13 ;если не конец строки
jnz sh1 ;то продолжить сдвиг
jmp no_shift ;закончить сдвиг
;вставка символов
insert: mov si,bx ;адрес вставляемой строки
;ищем конец строки
sh3: cmp byte ptr [si],13;если конец строки
jz sh2 ;то нашли, переход
inc si ;следующий символ строки
jmp sh3 ;продолжить поиск
sh2:
mov di,si ;адрес конца строки
sub di,cx ;вычитая отрицательное кол-во символов прибавляем его
sh4: cmp si,bx ;если зашли за начало слова
jb no_shift ;то закончить сдвиг
mov al,[si] ;перенести очередной
mov [di],al ;символ
dec si ;перейти к следующим
dec di ;символам
jmp sh4 ;продолжить сдвиг
no_shift:
pop ax ;восстановить регистры
pop cx
pop di
pop si
ret ;выйти из подпрограммы
shift endp
end start
вод строки, находим слова через цикл, сравниваем символы с искомыми, если совпадают, то заменяем слово.
.data
BUFSIZE equ 200 ; константы задать с помощью директивы EQU;
msg0 db 13,10,'Input set of letters: $'
msg3 db 13,10,'Input new word: $'
msg1 db 13,10,'Input text. Empty string - finish:',13,10,'$'
msg2 db 13,10,'Result: $'
set db BUFSIZE,BUFSIZE+1 dup(0) ;выделить буфер для хранения 200 символов набора символов
wrd db BUFSIZE,BUFSIZE+1 dup(0) ;выделить буфер для хранения 200 символов другого слова
buf db BUFSIZE,BUFSIZE+1 dup(0) ;выделить буфер для хранения 200 символов строки
.stack 256
.code
start:
mov ax,@data ;Настраиваем сегментные регистры
mov ds,ax
mov es,ax
mov ah,9 ;функция вывода сообщения на экран
lea dx,msg0 ;выводимое сообщение
int 21h ;выводим на экран
mov ah,0ah ;функция ввода строки с клавиатуры
mov dx,offset set ;буфер куда вводить
int 21h ;пользователь вводит в текст в buf
mov ah,9 ;функция вывода сообщения на экран
lea dx,msg3 ;выводимое сообщение
int 21h ;выводим на экран
mov ah,0ah ;функция ввода строки с клавиатуры
mov dx,offset wrd ;буфер куда вводить
int 21h ;пользователь вводит в текст в buf
mov ah,9 ;функция вывода сообщения на экран
lea dx,msg1 ;выводимое сообщение
int 21h ;выводим на экран
mainlp: посимвольный ввод символов
mov ah,0ah ;функция ввода строки с клавиатуры
mov dx,offset buf ;буфер куда вводить
int 21h ;пользователь вводит в текст в buf
cmp buf[1],0 ;если строка не пустая
jnz q1 ;продолжить
jmp ex ;если пустая - выйти, него в ней менять
q1: lea si,buf[2] ;начало строки
lp1: ; поиск начала очередного слова
mov al,[si] ;прочитать очередной символ
cmp al,13 ;если конец строки
jz fin1 ;то закончить
cmp al,' ' ;если не пробел
jnz m1 ;то переход
inc si ;следующий символ
jmp lp1 ;продолжить поиск начала слова
m1: mov dx,si ;запомнить адрес начала слова
lp2:; поиск конца слова
mov al,[si] ;прочитать очередной символ
cmp al,13 ;если конец строки
jz m2 ;то закончить слово
cmp al,' ' ;если пробел
jz m2 ;то закончить слово
inc si ;следующий символ
jmp lp2 ;продолжить поиск конца слова
m2: mov ax,si ;адрес конца слова
sub ax,dx ;вычесть адрес начала, получили длину
lea bx,set[2] ;начало множества символов
mov cl,set[1] ;количество символов в множестве
a2: mov di,dx ;адрес начала слова
mov ch,[bx] ;взять очередную букву из набора
mov bp,ax ;длина слова
a1: cmp ch,[di] ;если очередная буква из набора входит в слово
jz vhodit ;то переход
inc di ;перейти с кледующей букве слова
dec bp ;уменьшить кол-во оставшихся в слове букв
jnz a1 ;продолжить пока не 0
; если дошли сюда, то буква не входит в слово
jmp lp1 ;поиск следующего слова
vhodit: inc bx ;перейти к следующей букве набора
dec cl ;уменьшить кол-во оставшихся в наборе букв
jnz a2 ;продолжить пока не 0
; если дошли сюда, значит все буквы набора есть в слове
mov bx,dx ;адрес начала слова
mov cx,ax ;длина слова
call shift ;удалить слово из строки
sub si,cx ;вычесть из текущего положения в строке длину слова
mov cl,wrd[1] ;длина другого слова
mov ch,0 ;сх=длина другого слова
neg cx ;сх=-длина другого слова
call shift ;вставить место под другое слово
add si,cx ;прибавить к текущему положению в строке длину другого слова
neg cx ;сх=длина другого слова
push si ;сохранить регистр
mov di,dx ;место куда вставлять (начало старого слова)
lea si,wrd[2] ;адрес другого слова
rep movsb ;скопировать другое слово в строку
pop si ;восстановить регистр
jmp lp1 ;поиск следующего слова
fin1:
mov ah,9 ;функция вывода сообщения на экран
lea dx,msg2 ;выводимое сообщение
int 21h ;выводим на экран
lea si,buf[2]
; Вывод строки на экран. Строка должна заканчиваться нулевым байтом
;ds:si - выводимая строка
mov ah,2 ;функция вывода символа на экран
os1: mov dl,[si] ;взять очередной символ из строки
cmp dl,13 ;если это конец строки
jz ose ;то закончить вывод
int 21h ;вывести очередной символ
inc si ;перейти к следующему символу
jmp os1 ;продолжить вывод
ose:
mov dl,13 ;возврат каретки
int 21h ;вывести возврат каретки
mov dl,10 ;перевод строки
int 21h ;вывести перевод строки
jmp mainlp ;продолжить ввод текста
ex: mov ax,4c00h ;закончить программу
int 21h
;сдвиг строки
;ds:bx - адрес сдвигаемой строки
;cx - количество сдвигаемых символов (число со знаком) положительное - сдвиг влево(удаление). Отрицательное - сдвиг вправо(вставка)
shift proc
push si ;сохранить регистры
push di
push cx
push ax
cmp cx,0 ;если ничего сдвигать не нужно
jz no_shift ;то закончить
jl insert ;если кол-во символов сдвига отрицательное, перейти к вставке
;удаление (сдвиг влево)
mov di,bx ;адрес-приемник строки
mov si,di ;адрес-источник строки
add si,cx ;больше приемника на количество сдвигаемых символов
sh1: lodsb ;загрузить символ из источника
stosb ;записать в приемник
cmp al,13 ;если не конец строки
jnz sh1 ;то продолжить сдвиг
jmp no_shift ;закончить сдвиг
;вставка символов
insert: mov si,bx ;адрес вставляемой строки
;ищем конец строки
sh3: cmp byte ptr [si],13;если конец строки
jz sh2 ;то нашли, переход
inc si ;следующий символ строки
jmp sh3 ;продолжить поиск
sh2:
mov di,si ;адрес конца строки
sub di,cx ;вычитая отрицательное кол-во символов прибавляем его
sh4: cmp si,bx ;если зашли за начало слова
jb no_shift ;то закончить сдвиг
mov al,[si] ;перенести очередной
mov [di],al ;символ
dec si ;перейти к следующим
dec di ;символам
jmp sh4 ;продолжить сдвиг
no_shift:
pop ax ;восстановить регистры
pop cx
pop di
pop si
ret ;выйти из подпрограммы
shift endp
end start
вод строки, находим слова через цикл, сравниваем символы с искомыми, если совпадают, то заменяем слово.
Соседние файлы в папке лабы