STACK_ SEGMENT ; Сегмент стека db 100 dup(?) ; резервируем 100 байт STACK_ ENDS DATA SEGMENT ; Сегмент данных ; выводимые сообщения Msg_Inp db 'Enter the line: $' Msg_Press db 10,13,'Press any key ...$' Msg_Res db 10,13,'Result: $' Msg_Count db 10,13,'Count: $' text1 db 10,13,'Number of words bigger then first: $' String db 41 ; максимальная длина вводимой строки len db ? ; длина введенной строки text db 41 dup(?) ; введенная строка min dw ? ; длина самого короткого слова count dw 0 ; количество слов после самого короткого ;------------ Proc StrCon -------------- Num dw ? ; Num:=? Поле в 1 байт StrNum db 5 dup (?),'$' ; Хранение результата перевода counter dw ? DATA ENDS CODE SEGMENT ;Сегмент кода ASSUME CS:CODE,DS:DATA,SS:STACK_ ;ассоциация сегментных регистров start: mov ax,data ; настройка сегментных регистров mov ds,ax ; сегмент данных mov es,ax ; вспомагательный сегментный регистр cld ; очистка флага направления ; строковые операции будут проводится слева на право ; приглашения к вводу строки и ее ввод lea dx,Msg_Inp ; адрес сообщения mov ah,9 ; номер функции вывода строки на экран int 21h ; прерывание ДОС - вывод строки mov ah,0ah ; функция ввода строки lea dx,String ; адрес структуры вводимой строки int 21h ; ввод строки - прерывание ДОС ; вывод сообщения Result mov ah,9 ; номер функции вывода строки на экран lea dx,Msg_Res ; адрес выводимого сообщения int 21h ; вывод сообщения ; нахождение первого слова mov ch,0 ; старший байт = 0 mov cl,len ; количество байт (символов) для сканирования lea di,text ; адрес строки mov al,' ' ; искомый символ mov dx,di ; начало самого короткого слова mov min,cx ; длина самого короткого слова find_space: mov si,di ; запомнить адрес начала текущего слова repne scasb ; сканировать пока не равно пробелу ; вычисление длины слова mov bx,di ; указывает на следующий символ после найденного sub bx,si ; вычесть адрес начала слова jz no_min ; перейти если длина=0 (подряд 2 пробела) cmp cx,0 ; если просканированна вся строка jz end_str ; перейти на метку dec bx ; реальная длина слова, т.к. di указывал на символ ; следующий за пробелом jz no_min ; перейти если длина=0 (подряд 2 пробела) end_str: cmp bx,min ; сравнение длины слова (ВХ) с самым коротким jae no_min ; если длина больше либо равна - то перейти mov min,bx ; иначе сохранить длину текущего как минимальную mov count,0 mov dx,si ; запомнить начало самого короткого слова no_min: push ax mov ax,count inc ax mov count,ax pop ax cmp cx,0 ; если просканированна не вся строка jnz find_space ; тогда перейти - продолжить сканирование ; устанавливаем после слова символ $ mov si,dx ; адрес начала слова mov bx,min ; длина слова mov byte ptr [si+bx],'$' ; запись символа после слова ; вывод слова mov ah,9 ; функция вывода сообщения int 21h ; вывод сообщения с адреса DX ;вывод количества слов после самого короткого lea dx, text1 call WrStr mov ax,count add ax,1 dec ax mov Num,ax call StrCon lea dx, StrNum call WrStr ; вывод сообщения о необходимости нажатия клавиши mov dx,OFFSET Msg_press ;адрес выводимого сообщения mov ah,09h ; функция вывода строки на экран int 21h ; прерывание DOS ; ожидаем нажатие клавиши mov ah,1 ; ввод символа с клавиатуры - задержка int 21h ; чистим буфер, ждем ввода ; завершение программы mov ah,4ch ; функция завершения программы int 21h ;_______________ ADD PROC ______________ ;-------------- Proc WrStr ------------- WrStr proc near push ax mov ah,09h int 21h pop ax ret WrStr endp ;-------------- Proc StrCon ------------ StrCon proc push ax push cx push dx push bx push si mov bx,-1 p1: inc bx xor ax,ax mov StrNum[bx],al cmp bx,3 jne p1 mov cx, 10 lea si, StrNum + 3 mov ax, Num p2: cmp ax, 10 jb p3 cwd div cx add dl, 30h mov [si], dl dec si jmp p2 p3: add al, 30h mov [si], al pop si pop bx pop dx pop cx pop ax ret StrCon endp ;________________ END __________________ CODE ENDS END start ; Start - метка начала исполнение программы