Найти и вывести самую длинную цепочку из слов одинаковой длины - Assembler
Формулировка задачи:
Кто знает Ассемблер помогите очень прошу.
№2 Задано текст, слова в котором разделены пробелами и знаками препинания.
Разработать программу, которая находит и выводит самую длинную цепочку из слов одинаковой длины. Если цепочек нет, то выводит сообщение об этом.(Цепочка - это последовательность из двух и более слов, находящихся рядом.)
Решение задачи: «Найти и вывести самую длинную цепочку из слов одинаковой длины»
textual
Листинг программы
- LOCALS
- .model small
- .stack 100h
- .data
- ;строка для исследования
- String db 'Mateusz Viste writes: DWOL is '
- db 'a tiny tool that computes and '
- db 'sends "Wake-on-LAN" packets. '
- db 'Wake-on-LAN (WOL) is an Ethernet '
- db 'standard that allows a computer to '
- db 'be turned on by a network message.', '$'
- Len dw $-String-1
- ;символы разделители слов
- DelimChars db '.,!?;:"() ', "'"
- LenDelimChars dw $-DelimChars
- ;переменные
- CrLf db 0Dh, 0Ah, '$' ;перевод троки
- CurrChain dw ? ;текущая длина цепочки
- CurrWordsLen dw ? ;длина слова в текущей цепочке
- StartChain dw ? ;адрес начала цепочки
- FinishChain dw ?
- MaxChain dw ? ;максимальная длина цепочки
- MaxWordsLen dw ? ;длина слова в максимальной цепочке
- MaxStartChain dw ? ;адрес начала цепочки
- MaxFinishChain dw ?
- msgNoChain db 'No chain', '$'
- .code
- main proc
- mov ax, @data
- mov ds, ax
- mov ax, 0
- mov CurrChain, ax
- mov CurrWordsLen, ax
- mov StartChain, ax
- mov FinishChain, ax
- mov MaxChain, ax
- mov MaxWordsLen, ax
- mov MaxStartChain, ax
- mov MaxFinishChain, ax
- lea si, String
- mov cx, Len
- ;пропускаем все разделители
- @@WhileDelimiter:
- mov al, [si]
- call IsDelimChar
- cmp ah, 0
- je @@NewWord
- inc si
- loop @@WhileDelimiter
- jcxz @@NewChain ;если строка закончилась - выйти, но перед этим оценить
- ;текущую цепочку
- ;найдено новое слово
- @@NewWord:
- mov dx, 0 ;длина очередного слова пока равна 0
- mov di, si ;сохраняем адрес начала слова
- ;пропускаем все буквы слова до разделителя
- @@WhileWord:
- mov al, [si]
- call IsDelimChar
- cmp ah, 0
- jne @@Break
- @@NextChar:
- inc dx ;увеличиваем длину слова
- inc si ;переходим к следующему символу
- loop @@WhileWord
- @@Break:
- ;сравниваем длину текущего слова с длиной слова в текущей цепочке
- cmp dx, CurrWordsLen
- jne @@NewChain ;если они не равны, то цепочка прервалась
- @@ContChain:
- ;если цепочка продолжается, то увеличить длину цепочки
- inc CurrChain
- mov FinishChain, si
- dec FinishChain
- jmp @@Next
- @@NewChain: ;иначе - цепочка прервалась
- ;инициализация параметров новой цепочки
- mov CurrChain, 1
- mov CurrWordsLen, dx
- mov StartChain, di
- mov FinishChain, si
- dec FinishChain
- jmp @@Next
- @@Next:
- mov ax, CurrChain ;сравниваем длину цепочки с максимальной
- cmp ax, MaxChain
- jbe @@SkipCopy
- ;копирование параметров максимальной цепочки
- mov ax, CurrChain
- mov MaxChain, ax
- mov ax, CurrWordsLen
- mov MaxWordsLen, ax
- mov ax, StartChain
- mov MaxStartChain, ax
- mov ax, FinishChain
- mov MaxFinishChain, ax
- @@SkipCopy:
- jcxz @@Finish
- jmp @@WhileDelimiter
- @@Finish:
- ;вывод результатов
- cmp MaxChain, 2
- jae @@ShowChain
- mov ah, 09h
- lea dx, msgNoChain
- int 21h
- jmp @@Exit
- @@ShowChain:
- mov si, MaxStartChain
- mov cx, MaxFinishChain
- sub cx, si
- add cx, 1
- call ShowSubStr
- @@Exit:
- mov ax, 4C00h
- int 21h
- main endp
- ;Определяет, принадлежит ли символ в al разделителям слов
- ;на входе
- ; al - символ
- ;на выходе
- ; ah - 0 (не разделитель), 1 (разделитель)
- IsDelimChar proc
- mov ah, 0
- pushf
- push si
- push di
- push cx
- push es
- push ds
- pop es
- lea di, DelimChars
- mov cx, LenDelimChars
- cld
- repne scasb
- jcxz @@Skip
- jnz @@Skip
- mov ah, 1
- @@Skip:
- pop es
- pop cx
- pop di
- pop si
- popf
- ret
- IsDelimChar endp
- ;процедура вывода подстроки
- ;на входе:
- ; ds:si - адрес первого символа подстроки
- ; cx - длина выводимой подсторки
- ShowSubStr proc
- push ax
- push bx
- push cx
- push dx
- mov ah, 40h
- mov bx, 1
- mov cx, cx
- mov dx, si
- int 21h
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- ShowSubStr endp
- end main
Объяснение кода листинга программы
- Объявление переменных в сегменте данных:
String
- строка для исследованияLen
- длина строки StringDelimChars
- символы разделители словLenDelimChars
- длина строки DelimCharsCrLf
- символ перевода строкиCurrChain
- текущая длина цепочкиCurrWordsLen
- длина слова в текущей цепочкеStartChain
- адрес начала цепочкиFinishChain
- адрес конца цепочкиMaxChain
- максимальная длина цепочкиMaxWordsLen
- длина слова в максимальной цепочкеMaxStartChain
- адрес начала максимальной цепочкиMaxFinishChain
- адрес конца максимальной цепочкиmsgNoChain
- сообщениеNo chain
- Инициализация переменных:
- Используются команды
mov
для установки начальных значений всех переменных в 0 -ax, CurrChain, CurrWordsLen, StartChain, FinishChain, MaxChain, MaxWordsLen, MaxStartChain, MaxFinishChain
- Используются команды
- Чтение строки и анализ слов:
- Используется цикл для чтения каждого символа в строке и анализа слов
- При обнаружении нового слова устанавливается длина и проверяется соответствие длины предыдущего слова текущей цепочке
- Оценка цепочек:
- Сравнение длины текущей цепочки со значениями максимальной длины цепочки, затем копирование параметров максимальной цепочки (если нужно)
- Вывод результатов:
- Печать сообщения
No chain
в случае отсутствия цепочек заданной длины или вывод максимальной цепочки при её наличии - Используются команды
mov
,lea
иint
для вывода сообщений с использованием прерываний DOS
- Печать сообщения
- Процедура IsDelimChar:
- Определение, принадлежит ли символ к разделителям слов
- Процедура ShowSubStr:
- Вывод подстроки на экран с использованием прерываний DOS
- Завершение программы:
- Программа завершается с использованием прерывания DOS
Этот код, возможно, написан на языке ассемблера для MS-DOS, так как используются прямые обращения к прерываниям DOS и регистрам процессора (например,
ax
,dx
,ah
).
- Программа завершается с использованием прерывания DOS
Этот код, возможно, написан на языке ассемблера для MS-DOS, так как используются прямые обращения к прерываниям DOS и регистрам процессора (например,
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д