Лаб9. Обработка одномерных символьных массивов

Цель работы: ознакомление с основными командами обработки символьных массивов.

Теоретическая часть

Все команды работы со строками (символьными массивами) могут оперировать со строками до 64 Kбайт. Команде может предшествовать префикс, который задает повторное выполнение команды заданное число раз, что облегчает обработку строк.

Все команды обработки строк имеют некоторые общие особенности. Строка (массив) может выступать в качестве операнда–источника, операнда–приемника или одновременно и источником, и приемником. По умолчанию, строка–источник располагается в сегменте данных, обычно адресуемом регистром DS, регистр SI (индекс источника) используется для адресации смещения в строке–источнике.

Строка–приемник располагается в дополнительном сегменте данных, обычно адресуемом регистром ES, регистр DI (индекс приемника) используется для адресации смещения в строке–приемнике. Регистры SI и DI должны быть инициализированы адресами массивов источника и приемника. Обрабатываемые строки могут содержать элементы стандартных типов (байт, слово или двойное слово).

Для строк можно явно переопределять сегмент с помощью префикса, например, DS:ARR1, DS:ARR2, а это означает, что обе строки находятся в одном сегменте. Если же загрузить регистры DS и ES одним значением, то обе строки смогут находиться в одном сегменте.

При выполнении любой из команд обработки строк значения регистров SI и DI изменяются, указывая на следующий элемент строки, требующий обработки. Шаг изменения зависит от значения флажка DF. Значение DF = 0 приводит к инкрементации регистров SI и DI, при DF = 1 – к декрементации. Если размерность элементов массива равна одному байту, значения регистров SI и DI изменяются после каждой операции на 1, при размерности WORD – на 2.

При использовании префикса повторения команды, количество повторений хранится в регистре CX. После каждой итерации значение регистра CX будет уменьшаться на единицу. Если CX = 1, команда выполнится только один раз и управление будет передано следующей команде.

Префиксы повторений REP, REPE, REPZ, REPNE и REPNZ

Префикс REP(repeat) используется с командами MOVS и STOS и интерпретируется как «повторять до конца строки» (пока CX отлично от 0).

Префиксы REPE и REPZ (repeat while equal, repeat while zero) идентичны и используются с командами CMPS и SCAS. В случае использования данных префиксов команда будет повторяться до тех пор, пока флажок ZF =1 и значение регистра CX отлично от 0. Префиксы REPNE и REPNZ (repeat while not equal, repeat while not zero) повторяют команду, пока ZF = 0 и CX отлично от 0.

Команда CLD

Команда CLD (CLear Direction flag) устанавливает флажок направления (DF) в 0 для автоматического увеличения значений регистров SI и DI (просмотр массива слева направо). Команда CLD других флажков не меняет.

Синтаксис: CLD

Команда STD

Команда STD (SeT Direction flag) устанавливает флажок направления (DF) в 1 для автоматического уменьшения значений регистров SI и DI (просмотр массива справа налево). Команда STD других флажков не меняет.

Синтаксис: STD

Команда MOVS

Команда MOVS (MOVe String) копирует байт, слово или двойное слово из строки–источника, адресованной регистром SI в строку–приемник, адресованную регистром DI. После копирования элемента значения регистров–указателей SI и DI автоматически сдвигаются на следующий элемент в зависимости от значения флажка направления DF. С префиксом повторения команда MOVS может быть использована для копирования блоков памяти.

Синтаксис: MOVs [<строка_приемник>, <строка_источник>]

MOVSB ;пересылка байта

MOVSW ;пересылка слова

MOVSD ;пересылка двойного слова

В команде MOVS операнды указывают только на тип элементов, а не на сами обрабатываемые элементы. Типы операндов можно задавать явно, используя команды MOVSB, MOVSW и MOVSD, сами операнды указывать необязательно. Команды работают, соответственно, с массивами, типы которых определяются последним символом команды: BBYTE, WWORD, DDWORD.

Команда CMPS

Команда CMPS (CoMPare String) сравнивает один элемент из строки–источника, адресованный регистром SI, с элементом строки–приемника, адресованным регистром DI. После сравнения элементов признак результата сохраняется во флажковом регистре и значения указателей SI и DI автоматически сдвигаются на следующий элемент в зависимости от значения флажка направления DF.

В сочетании с префиксом условного повторения данную команду можно использовать для поиска элемента, соответствующего заданному условию. Тип элемента соответствует типам операндов.

Синтаксис: CMPS [<строка_приемник>, <строка_источник>]

cmpsb ;сравнение байта

cmpsw ;сравнение слова

cmpsd ;сравнение двойного слова

Команда SCAS

Команда SCAS (SCAn String) сравнивает элемент строки–приемника, адресованный регистром DI, с содержимым регистра al/ax/eax, изменяет содержимое регистра DI, формирует признак результата и сохраняет его во флажковом регистре (флажки AF, CF, OF, PF, SF, ZF). Команда SCAS может быть использована с условным префиксом повторения для сравнения символов строки с элементом, хранящимся в регистре.

Сравнение будет производиться до тех пор, пока не будет найдено совпадение (REPNE) или несовпадение (REPE). В случае, когда условие ни разу не выполняется, цикл прекратится после заданного в CX количества раз.

Синтаксис: SCAS [< строка_приемник >]

SCASB ;сканирование байта

SCASW ;сканирование слова

SCASD ;сканирование двойного слова

Команда LODS

Команда LODS (LOaD String) копирует один элемент (байт, слово или двойное слово) из строки–источника в регистр al/ax/eax и изменяет содержимое регистра SI для возможности копирования следующих элементов строки. Команда LODS может быть использована с префиксом повторения, но обычно префикс не используется, так как запомнится только результат последнего копирования.

Синтаксис: LODS [<строка_источник>]

LODSB ;загрузка байта

lodsw ; загрузка слова

lodsd ; загрузка двойного слова

Команда STOS

Команда STOS (STOre String) копирует байт, слово или двойное слово из регистра al/ax/eax в строку–приемник, адресованную регистром DI. После выполнения команды регистр DI обновляется, указывая на следующий символ строки. Если перед командой использовать префикс безусловного повторения, можно всю строку инициализировать одним и тем же значением, например – заполнить строку символами пробела или числами 0.

Синтаксис: STOS [< строка_приемник>]

STOSB ;запись байта

STOSW ;запись слова

STOSD ;запись двойного слова

Пример

С клавиатуры вводятся 2 строки. Вывести сообщение “Yes”, если строки совпадают, и “No” в противном случае.

.data
str1	db	100 dup (?)	;буфер ввода1
str2 	db	100 dup ('$')	;буфер ввода2
len1 	dw 	?
len2 	dw 	?
.code
	mov ax, @data	;инициализация регистров ds и es
	mov ds, ax	;регистры ds и es инициализированы одним и тем же 
	mov es, ax	;зачением, т.к. строки str1 и str1 находятся 
			;в одном и том же сегменте
	...
	;ввод 2–х строк
	;длина введенных строк сохраняется в len1 и len2
	...
	lea di, str2	;в di – адрес строки–приемника
	lea si, str1	;в si – строки–источника
	cld		;задаем направление просмотра 
;строки слева направо
	mov cx, len1	;cx – количество повторений для repe
	cmp cx, len2	;сравниваем длины строк
	jne	NO	;если длины строк не совпадают, идем на NO
repe	cmpsb		;сравниваем строки
	jne NO		;если строки не совпадают, переход на NO
                        ;вывод сообщения “Yes”
...
	jmp	finish
NO:	...		;вывод сообщения “No”
finish: ...

Задания

  • Составьте программу (вариант A) на языке Ассемблер, которая читает строку символов с клавиатуры и обрабатывает ее, используя команды работы со строками.
  • Составьте программу (вариант B), используя команды сравнения, перехода и команды организации циклов.
  1. Заменить в строке все заглавные буквы ‘A’ на ‘а’.
  2. Определить, является ли введенная строка целым положительным числом.
  3. Найти первый символ ‘*’ в строке и заменить его на символ ‘#’.
  4. Найти последний символ ‘?’ в строке и заменить его на символ ‘!’.
  5. Подсчитать количество слов в предложении (разделитель между словами – символ пробела).
  6. Удалить в строке повторяющиеся пробелы.
  7. Найти в строке все слова длиннее заданного количества символов (разделитель между словами – символ пробела).
  8. Найти в строке положение последней запятой и поменять ее на первый непробельный символ строки.
  9. Для всех слов в строке, заканчивающихся на “ing”, заменить окончания на “ed” (разделитель между словами – символ пробела).
  10. Заменить в строке все символы ‘–’, предшествующие первому символу ‘+’, на символ ‘*’.
  11. Определить, сколько раз каждая буква встречается в заданном предложении.
  12. Заменить в строке каждую точку ‘.’ на многоточие “…”.
  13. Найти в строке все слова, в которых буква ‘a’ встречается более двух раз (разделитель между словами – символ пробела).
  14. Найти в строке все слова, состоящие не более чем из 6 символов (разделитель между словами – символ пробела).
  15. Определить, расположены ли слова предложения в алфавитном порядке (разделитель между словами – символ пробела).
  16. Определить, начинается ли каждое следующее слово в предложении с последней буквы предыдущего слова (разделитель между словами – символ пробела).
рассказать друзьям и получить подарок

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Translate Переводчик

Подписка на новости

SmartResponder.ru
Ваш e-mail: *
Ваше имя: *

Хостинг для Wordpress сайтов