
Лабораторная работа № 4
Строковые команды
Содержание работы
цель работы
введение
строковые (цепочечные) команды
префиксы повторения
пример программы
порядок выполнения работы
содержание отчета
варианты заданий
заключение
приложения
Цель работы
Целью работы является изучение строковых команд и особенностей их использования.
Введение
Среди разнообразных методов адресации, реализуемых различными процессорами, весьма удобным является косвенный регистровый автоинкрементный/автодекрементный, который отличается от обычного косвенного регистрового тем, что, адрес операнда, содержащийся в регистре, до или после использования увеличивается или уменьшается. В ассемблерах для процессора VAX (Virtual Address eXtended) фирмы Digital Equipment Corporation (DEC), например, косвенная адресация обозначается как (R3), (R5), а косвенная автоинкрементная/автодекрементная – как (R3)+, –(R5). Заметим, что в этих случаях говорят о поставтоинкрементной (увеличение после использования) и предавтодекрементной (уменьшение перед использованием) косвенной адресации. Взаимная согласованность этих вариантов позволяет реализовать стековую адресацию как частный случай косвенной автоинкрементной/автодекрементной.
Фирма Intel, идя по пути разбиения множества команд процессора на обособленные группы, выделила т. н. «строковые» команды в особую группу. Отличие этих команд, называемых также «цепочечными», от остальных состоит в следующем:
только в них используется автоинкрементная/автодекрементная адресация
только в них возможно расположение обоих операндов в памяти (M – M)
только в них по умолчанию используется сегментный регистр ES
применяется неявная адресация с использованием регистров SI, DI
Строковые (цепочечные) команды
Под цепочкой (строкой) понимается последовательность однотипных данных в памяти, а цепочечной командой называется команда, выполняемая над каждым элементом цепочки. Элементами цепочки для 32-разрядного процессора могут быть байты (byte), слова (word)и двойные слова (dword). В наборе команд процессоров Intel, начиная с 8086/8088, имеются примитивные цепочечные команды, которые облегчают обработку таких последовательностей данных, представляющих собой одномерные массивы. Однократное применение такой примитивной команды обрабатывает один элемент массива (цепочки), и обычно используется в цикле. В ассемблерной мнемонике к названию этих команд добавлена буква «S», как сокращение от string (строка). Машинные команды, соответствующие этим, формируются трех типов для каждой из приведенных команд, в зависимости от типа операндов (byte, word, dword). Например, для мнемоники MOVS существуют три команды: MOVSB, MOVSW, MOVSD. Если в операции участвует аккумулятор, то, соответственно, это будет AL, AX или EAX.
Используемые в строковых командах регистры, содержащие адреса элементов цепочки, называются индексными регистрами: SI (Source Index register – индексный регистр источника) и DI (Destination Index register– индексный регистр приемника). Применение регистров не указывается, а подразумевается по умолчанию для каждой команды (неявная адресация). В строковых командах сегментные адреса цепочек также по умолчанию расположены в регистрах DS (цепочка-источник) и ES (цепочка-приемник). Впрочем, для адресации источника сегментный регистр DS можно заменить на другой при помощи префикса замены сегмента. Использование сегментного регистра ES в строковых командах изменить нельзя. Замечательным свойством строковых команд является то, что содержимое индексного регистра после использования в качестве адреса элемента цепочки изменяется на величину, кратную размеру элемента (на 1 для байта, на 2 для слова, на 4 для двойного слова). Это, собственно, и есть автоинкрементная/автодекрементная адресация, являющаяся сутью использования строковых команд. Увеличение (автоинкремент) или уменьшение (автодекремент) адреса происходит в зависимости от заранее выбранного направления продвижения по цепочке: вперед (+) или назад (–).
Список строковых команд:
MOVS – move string переслать строку ((ES:DI) (DS:SI))
CMPS – compare string сравнить строки ((DS:SI) – (ES:DI))
LODS – load string загрузить строку (Accumulator (DS:SI))
STOS – store string запомнить строку ((ES:DI) Accumulator)
SCAS – scan string сканировать строку (Accumulator – (ES:DI))
INS – input string ввести строку ((ES:DI) In Port)
OUTS – output string вывести строку (Out Port (DS:SI))
Если в команде указан операнд (это символическое имя массива в сегменте данных), то он не учитывается как адрес операнда (не загружается в регистры!), а служит лишь для определения типа операнда и, может быть, для лучшей читаемости исходного текста программы. Если операнд не указывается, то нужно явно применить конкретную мнемонику с буквой типа операнда на конце (-b, -w, -d). В любом случае необходимо до применения команды загрузить начальные значения всех используемых регистров (DS, SI, ES, DI). Обратите внимание на то, что для указания сегмента, в котором находится цепочка-приемник, используется регистр ES. В отличие от регистра DS, который обычно уже инициализирован в начале программы, регистр ES, возможно, перед использованием строковых команд, необходимо инициализировать, загрузив в него адрес сегмента, содержащего цепочку-приемник. Т. к. большинство программ на ассемблере имеют один сегмент данных (содержащий как цепочку-источник, так и цепочку-приемник), на который уже указывает регистр DS, то достаточно загрузить в ES то же значение, что и в DS, выполнив, например, следующий код:
push DS
pop ES
Индексные регистры загружаются адресами цепочек с использованием оператора offset или командами LDS, LES:
.data ; сегмент данных
str1 db ‘ABCDEF’ ; строка-источник
str2 db ‘abcdef’ ; строка-приемник
adrstr1 dd str1 ; здесь будет указатель на str1
adrstr2 dd str2 ; здесь будет указатель на str2
.code ; сегмент кода
. . .
lds si,adrstr1 ; адрес источника в DS:SI
les di,adrstr2 ; адрес приемника в ES:DI
или:
push ds
pop es ; сегм. адрес назначения в ES
mov si,offset string1 ; смещение источника в SI
mov di,offset string2 ; смещение приемника в SI
Направление продвижения по цепочке определяется значением флага df (direction flag) в регистре флагов процессора. Если df=0, то цепочка просматривается вперед (с увеличением адресов, т.е. инкрементированием индексного регистра), если же df=1, то цепочка просматривается назад (с уменьшением адресов, т.е. декрементированием индексного регистра). Устанавливается значение флага направления командами CLD и STD:
cld ; очистить флаг df (направление вперед)
std ; установить флаг df (направление назад)