Заменить в каждом слове первую букву на прописную - Assembler
Формулировка задачи:
Заменить в каждом слове первую букву на прописную
Решение задачи: «Заменить в каждом слове первую букву на прописную»
textual
Листинг программы
.model small .stack 100h .data str1 db "vtr1 ztr4 Str5 ktr6 ytr7 atr8" len dw $-str1 res db 255 dup (?) .code begin: mov ax, @data mov ds, ax mov es, ax lea si, str1 lea di, res mov cx, len inc cx ; добавляем 1, т.к. обработаем первый символ отдельно lodsb jmp c ; входим внутрь цикла c1: lodsb cmp al, ' ' ; сверяем с пробелом jne skip ; если не пробел - goto skip stosb ; иначе - загружаем пробел и работаем со след. символом lodsb ; загружаем след. символ c: cmp al, 97 ; проверяем диапазон 97..122 (прописные буквы) jl c2 cmp al, 122 jg c2 sub al, 32 ; если попадает в диапазон прописных букв - вычитаем 32, так как диапазон строчных букв - 95..90 c2: dec cx ; вычитаем СХ, так как мы в рамках одной итерации обработали два символа skip: stosb ; очередной символ - в строку-приемник loop c1 ; цикл mov res[si], '$' ; выводим строку результата lea dx, res mov ah, 9 int 21h mov ax, 4c00h int 21h ends end begin
Объяснение кода листинга программы
- Объявляется модель памяти и размер стека.
- Объявляются переменные данных:
str1- строка для обработки, содержащаяvtr1 ztr4 Str5 ktr6 ytr7 atr8,len- длина строкиstr1,res- строка для хранения результата длиной 255 символов.
- Начинается исполняемый код:
- Загружается адрес сегмента данных в регистр
axи также устанавливается сегмент данных в регистрds. - Регистр
esтакже устанавливается в сегмент данных для дальнейшего использования. - Адрес строки
str1загружается в регистрsi(источник). - Адрес строки
resзагружается в регистрdi(приемник). - В регистр
cxзагружается длина строкиlenплюс единица (т.к. первый символ будет обработан отдельно). - Байт из памяти, адресуемый регистром
si, загружается в регистрalи инкрементируется счетчикsi. - Происходит переход к метке
c(т.е. начало цикла обработки).
- Загружается адрес сегмента данных в регистр
- В цикле происходит следующее:
- Байт из памяти, адресуемый регистром
si, загружается в регистрal. - Происходит сравнение содержимого
alс символом пробела. - Если содержимое
alне равно пробелу, происходит переход к меткеskip. - Если содержимое
alравно пробелу, то символ пробела записывается в память по адресуdi, затем байт из памяти, адресуемый регистромsi, загружается в регистрal. - Сравнивается содержимое
alс ASCII значением маленькой буквы 'a' (97). Если оно меньше, происходит переход к меткеc2. - Если содержимое
alбольше ASCII значения маленькой буквы 'z' (122), также происходит переход к меткеc2. - Иначе из содержимого
alвычитается 32, переводя его в верхний регистр (прописную букву). - Уменьшается счетчик
cx. - Записывается содержимое
alв память, адресуемую регистромdi. - Проверяется счетчик
cx. Если он не равен 0, происходит переход на меткуc1.
- Байт из памяти, адресуемый регистром
- После цикла:
- В память, адресуемую регистром
si, записывается символ '$' для завершения строки. - Адрес строки
resзагружается в регистрdx. - Выполняется вывод строки с помощью прерывания
int 21h, ah=9. - Программа завершается с использованием прерывания
int 21hи функции завершения4c00h.
- В память, адресуемую регистром