Эти команды также называют командами обработки строк символов. Названия почти синонимичны.
Отличие в том, что под строкой символов здесь понимается последовательность байт, а цепочка — это более общее название для случаев, когда элементы последовательности имеют размер больше байта — слово или двойное слово. Таким образом, цепочечные команды позволяют проводить действия над блоками памяти, представляющими собой последовательности элементов следующего размера:
· 8 бит — байт;
· 16 бит — слово;
· 32 бита — двойное слово.
Содержимое этих блоков для микропроцессора не имеет никакого значения. Это могут быть символы, числа и все что угодно. Главное, чтобы размерность элементов совпадала с одной из перечисленных и эти элементы находились в соседних ячейках памяти.
Всего в системе команд микропроцессора имеется семь операций-примитивов обработки цепочек.
Каждая из них реализуется в микропроцессоре тремя командами, в свою очередь, каждая из этих команд работает с соответствующим размером элемента — байтом, словом или двойным словом. Особенность всех цепочечных команд в том, что они, кроме обработки текущего элемента цепочки, осуществляют еще и автоматическое продвижение к следующему элементу данной цепочки.
|
|
|
Перечислим операции-примитивы и команды, с помощью которых они реализуются, а затем подробно их рассмотрим:
· пересылка цепочки:
Movs адрес_приемника,адрес_источника
Movsb
Movsw
Movsd
· сравнение цепочек:
Cmps адрес_приемника,адрес_источника
Cmpsb
Cmpsw
Cmpsd
· сканирование цепочки:
Scas адрес_приемника
Scasb
Scasw
Scasd
· загрузка элемента из цепочки:
Lods адрес_источника
Lodsb
Lodsw
Lodsd
· сохранение элемента в цепочке:
Stos адрес_приемника
Stosb
Stosw
Stosd
· получение элементов цепочки из порта ввода-вывода:
Ins адрес_приемника,номер_порта
Insb
Insw
Insd
· вывод элементов цепочки в порт ввода-вывода:
Outs номер_порта,адрес_источника
Outsb
Outsw
Outsd
Логически к этим командам нужно отнести и так называемые префиксы повторения. Вспомните формат машинной команды и его первые необязательные байты префиксов. Один из возможных типов префиксов — это префиксы повторения. Они предназначены для использования цепочечными командами.
Префиксы повторения имеют свои мнемонические обозначения:
rep
repe или repz repne или repnz
Эти префиксы повторения указываются перед нужной цепочечной командой в поле метки. Цепочечная команда без префикса выполняется один раз. Размещение префикса перед цепочечной командой заставляет ее выполняться в цикле.
Отличия приведенных префиксов в том, на каком основании принимается решение о циклическом выполнении цепочечной команды: по состоянию регистра ecx/cx или по флагу нуля zf:
|
|
|
· префикс повторения rep (REPeat). Этот префикс используется с командами, реализующими операции-примитивы пересылки и сохранения элементов цепочек — соответственно, movs и stos.
Префикс rep заставляет данные команды выполняться, пока содержимое в ecx/cx не станет равным 0. При этом цепочечная команда, перед которой стоит префикс, автоматически уменьшает содержимое ecx/cx на единицу. Та же команда, но без префикса, этого не делает;
· префиксы повторения repe или repz (REPeat while Equal or Zero). Эти префиксы являются абсолютными синонимами.
Они заставляют цепочечную команду выполняться до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен 1. Как только одно из этих условий нарушается, управление передается следующей команде программы. Благодаря возможности анализа флага zf, наиболее эффективно эти префиксы можно использовать с командами cmps и scas для поиска отличающихся элементов цепочек.
· префиксы повторения repne или repnz (REPeat while Not Equal or Zero). Эти префиксы также являются абсолютными синонимами. Их действие на цепочечную команду несколько отличается от действий префиксов repe/repz. Префиксы repne/repnz заставляют цепочечную команду циклически выполняться до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен нулю.
При невыполнении одного из этих условий работа команды прекращается. Данные префиксы также можно использовать с командами cmps и scas, но для поиска совпадающих элементов цепочек.
Следующий важный момент, связанный с цепочечными командами, заключается в особенностях формирования физического адреса операндов адрес_источника и адрес_приемника.
Цепочка-источник, адресуемая операндом адрес_источника, может находиться в текущем сегменте данных, определяемом регистром ds.
Цепочка-приемник, адресуемая операндом адрес_приемника, должна быть в дополнительном сегменте данных, адресуемом сегментным регистром es. Важно отметить, что допускается замена (с помощью префикса замены сегмента) только регистра ds, регистр es подменять нельзя. Вторые части адресов - смещения цепочек — также находятся в строго определенных местах. Для цепочки-источника это регистр esi/si (Source Index register — индексный регистр источника). Для цепочки-получателя это регистр edi/di (Destination Index register - индексный регистр приемника). Таким образом, полные физические адреса для операндов цепочечных команд следующие:
· адрес_источника — пара ds:esi/si;
· адрес_приемника — пара es:edi/di.
Вы, наверное обратили внимание на то, что все семь групп команд, реализующих цепочечные операции-примитивы, имеют похожий по структуре набор команд. В каждом из этих наборов присутствует одна команда с явным указанием операндов и три команды, не имеющие операндов. На самом деле, набор команд микропроцессора имеет соответствующие машинные команды только для цепочечных команд ассемблера без операндов. Команды с операндами транслятор ассемблера использует только для определения типов операндов. После того как выяснен тип элементов цепочек по их описанию в памяти, генерируется одна из трех машинных команд для каждой из цепочечных операций. По этой причине все регистры, содержащие адреса цепочек, должны быть инициализированы заранее, в том числе и для команд, допускающих явное указание операндов. В силу того, что цепочки адресуются однозначно, нет особого смысла применять команды с операндами. Главное, что вы должны запомнить, — правильная загрузка регистров указателями обязательно требуется до выдачи любой цепочечной команды.
Последний важный момент, касающийся всех цепочечных команд, — это направление обработки цепочки. Есть две возможности:
· от начала цепочки к ее концу, то есть в направлении возрастания адресов;
· от конца цепочки к началу, то есть в направлении убывания адресов.
|
|
|
Как мы увидим ниже, цепочечные команды сами выполняют модификацию регистров, адресующих операнды, обеспечивая тем самым автоматическое продвижение по цепочке. Количество байт, на которые эта модификация осуществляется, определяется кодом команды. А вот знак этой модификации определяется значением флага направления df (Direction Flag) в регистре eflags/flags:
· если df = 0, то значение индексных регистров esi/si и edi/di будет автоматически увеличиваться (операция инкремента) цепочечными командами, то есть обработка будет осуществляться в направлении возрастания адресов;
· если df = 1, то значение индексных регистров esi/si и edi/di будет автоматически уменьшаться (операция декремента) цепочечными командами, то есть обработка будет идти в направлении убывания адресов.
Состоянием флага df можно управлять с помощью двух команд, не имеющих операндов: cld (Clear Direction Flag) — очистить флаг направления. Команда сбрасывает флаг направления df в 0. std (Set Direction Flag) — установить флаг направления. Команда устанавливает флаг направления df в 1.
Это вся информация, касающаяся общих свойств цепочечных команд. Далее мы более подробно рассмотрим каждую операцию-примитив и команды, которые ее реализуют. При этом более подробно мы будем рассматривать одну команду в каждой группе цепочечных команд — команду с операндами. Это будет делаться из тех соображений, что это более общая команда в смысле ограничений, накладываемых на типы операндов.






