sseg segment stack ;объявление стека размером 64 байта db 64 dup(?) sseg ends dseg segment ;объявление сегмена данных mlen db 100 ; | alen db ? ; | str db 100 dup(?) ;|структура, необходимая для ввода строки при помощи 10 функции прерывания ДОС ;mlen - максимальное количество символов, которые можно ввести ;alen - реальное количество введённых символов ;str - непосредственно введённая строка result db 100 dup(?) ;результат обработки строки inv db 13,10,'Enter the string (max len 100 chars):',13,10,'$' ;приглашение юзеру на ввод данных letters db '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM' ;| db 'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮйцукенгшщзхъфывапролджэячсмитьбюёЁ' ;|символы, считающиеся буквами nltrs db nltrs-letters ;количество букв first_len dw 0 ;длина первого слова; если 0 - значит ещё ни одно слово не найдено res db 13,10,'Result string is:',13,10,'$' ; key db 13,10,'Press any key...',13,10,'$' ; dseg ends cseg segment assume cs:cseg,ss:sseg,ds:dseg main proc far push ds xor ax,ax push ax mov ax,dseg mov ds,ax mov es,ax ;всё аналогично предыдущей задаче ^^ ;------------- lea dx,inv mov ah,9 int 21h ;вывод строки inv lea dx,mlen mov ah,10 int 21h ;ввод строки xor si,si ; обнуление si (si указывает на 1й символ введённой строки) lea bx,result ;bx указывает на result mov dl,alen ;| xor dh,dh ;|запись в dx длины введённой строки mov ch,dh ;обнуление ch process: mov al,str[si] ;в al - символ, на который указывает si lea di,letters ;di указывает на letters mov cl,nltrs ;в cl - количество букв repne scasb ;проверка, является ли символ в al буквой je letter ;если да - переходим на letter mov [bx],al ;если нет - пишем символ в результимрующую строку inc bx ;переходим inc si ;к следующему символу cmp si,dx ;если не достигнут конец строки jl process ;продолжаем jmp over ;а иначе - заканчиваем обработку letter: xor bp,bp ;обнуляем bp (он будет хранить длину текущего слова) push si ;сохраняем в стеке si _word: inc bp ;увеличиваем счётчик длины текущего слова inc si ;переходим к следующему символу cmp si,dx ;если достигнут конец строки jge wordover ;то слово закончилось, переходим на метку wordover ;иначе mov al,str[si] ;в al - символ, на который указывает si lea di,letters ;di указывает на letters mov cl,nltrs ;в cl - количество букв repne scasb ;проверка, является ли символ в al буквой je _word ;если да - переходим на _word (т.е. продолжаем считать длину текущего слова) wordover: ;слово закончилось pop di ;si, которое мы перед этим сохранили в стеке (то, которое указывает на начало слова) вытаскиваем из стека и пишем в di mov cx,first_len ;в cx читаем длину первого слова test cx,cx ;проверка сх на 0 jnz non_1st_word ;если не 0 - переход на non_1st_word mov cx,bp ;иначе - запоминаем длину первого слова mov first_len,cx ;да, запоминаем non_1st_word: cmp cx,bp ;равна ли длина текущего слова длине первого слова? jne dont_copy ;если нет - переходим на dont_copy lea si,str ;если да - копируем слово из исходной строки в результирующую add si,di ;si указывает на начало слова относительно начала сегмента данных mov di,bx ;di указывает на позицию в результирующей строке, куда надо скопировать слово rep movsb ;копирование sub si,offset str ;si указывает на символ после слова, относительно начала строки mov bx,di ;bx указывает на позицию в результирующей строке, куда надо писАть следующий символ dont_copy: cmp si,dx ;если не достигнут конец строки jl process ;то переходим к следующему символу over: ;иначе заканчиваем обработку mov byte ptr[bx],'$' ;пишем в конец результирующей строки сивол $ - необходимо для вывода строки функцией 9 ;прерывания ДОС ($ указывает на конец строки) lea dx,res mov ah,9 int 21h ;вывод строк lea dx,result int 21h lea dx,key int 21h xor ax,ax ;| int 16h ;|ожидание нажатия клавиши ;------------- ret main endp cseg ends end main |