Команды обработки строк

Эти команды позволяют производить действия над блоками байтов или слов памяти объемом до 64 Кбайт, которые трактуются как строки двоичных кодов. Фактически двоичные строки могут быть числовыми значениями или символьными значениями, для команд это безразлично. Рассматриваемые в этом параграфе команды приведены в таблице:

Мнемокод Формат
Префиксы повторения REP REP
REPE / REPZ REPE / REPZ
REPNE / REPNZ REPNE / REPNZ
Пересылка MOVS MOVS строка_приемник, строка_источник
MOVSB MOVSB
MOVSW MOVSW
Сравнение CMPS CMPS строка_приемник, строка_источник
CMPSB CMPSB
CMPSW CMPSW
Сканирование SCAS SCAS строка_приемник
SCASB SCASB
SCASW SCASW
Загрузка
LODS LODS строка_источник
LODSB LODSB
LODSW LODSW
Сохранение STOS STOS строка_приемник
STOSB STOSB
STOSW STOSW

Обращает на себя внимание тот факт, что группы команд одинакового действия насчитывают по 3 команды, у которых изменяется только последняя буква мнемокода. Объясняется это тем, что фактически процессор выполняет только команды без операндов, на которые транслятор замещает команды с операндами. Эти команды с операндами нужны транслятору только для тех целей, чтобы определить, будут в операциях участвовать байты (команды имеют конечным символом мнемокода символ В) или слова (команды имеют конечным символом мнемокода символ W). В командах обработки строк по умолчанию предполагается, что строка_приемник находится в дополнительном сегменте данных, а строка_источник – в основном. Процессор адресует строку_приемник через регистр DI, а строку_ источник – через регистр SI. Все команды являются групповыми, поэтому автоматически модифицируют указатели в регистрах DI и SI для адресации следующего элемента обрабатываемых строк. В операциях для адресации следующего элемента обрабатываемых строк. В операциях “участвует” флаг направления DF, значение которого определяет, будут ли значения регистров DI и SI увеличиваться или уменьшаться при выполнении групповой команды. Если флаг DF равен 0, то значения регистров DI и SI увеличиваются ( что равносильно выполнению команды INC), в противном случае значения регистров DI и SI уменьшаются (что равносильно выполнению команды DEC после обработки очередного символа). Флаг направления может быть установлен в 0 командой CLD или установлен в 1 командой STD. И, наконец, чтобы одной командой можно было обрабатывать группу последовательных элементов памяти, перед командой указывается префикс повторения.



Как видно из таблицы, в Ассемблере существуют 3 вида префиксов повторения. Количество повторений извлекается из регистра_счетчика CX, также как и при организации циклов. Так, команды

CLD

MOV CX, 500

REP MOVS DEST, SOURCE

приведут к пересылке 500 байтов или слов (это зависит от описания переменных DEST и SOURCE) из области памяти SOURCE в область памяти DEST. Аналогично командам цикла при каждом повторении групповой команды с префиксом значение счетчика повторений уменьшается на 1. Префикс REPE / REPZ используется, если групповую команду необходимо прервать, когда сбрасывается в 0 флаг ZF. Следовательно, применять этот префикс нужно к командам, воздействующим на флаг ZF, например, к команде сравнения строк CMPS:

CLD

MOV CX, 100

REP E CMPS DEST, SOURCE

Эта группа команд сравнивает строки DEST и SOURCE до тех пор, пока элементы в сравниваемых строках совпадают или пока не просмотрены все 100 элементов сравниваемых строк (или иначе действие этих команд можно определить как поиск первого несовпадения строк). Действие префикса REPNE / REPNZ противоположно действию REPE / REPZ. Так, команды

CLD

MOV CX, 100

REP NE CMPS DEST, SOURCE

Сравнивают строки до первого совпадения или до конца строки, если совпадение в соответствующих позициях строк не будет обнаружено.

Механизм действия групповых команд MOVS и CMPS понятен из приведенных примеров, причем MOVS не отличатся по действию от MOV, а вот CMPS в отличие от CMP вычитает операнд_приемник из операнда_источника, что необходимо учитывать при выборе команды условного перехода после сравнения (используйте для выбора следующую таблицу).

Условие перехода Следующая за CMPS команда
Числа без знака Числа со знаком
Источник больше приемника JA JG
Источник равен приемнику JE JE
Источник не равен приемнику JNE JNE
Источник меньше приемника JB JL
Источник меньше приемника или равен ему JBE JLE
Источник больше приемника или равен ему JAE JGE

Особенностью групповых команд является то, что при использовании префиксов REPE / REPZ или REPNE / REPNZ неизвестно, было обнаружено совпадение или несовпадение или нет (просмотрены все элементы строки). Выяснить имевшую место ситуацию можно, используя команды проверки флага ZF, например, следующим образом:



CLD

MOV CX, 100

REP NE CMPS DEST, SOURCE ;найти совпадение элементов строк

JNE NOT_FOUND ;совпадение обнаружено?

. . . . . . . . ; да. Продолжим обработку этими

. . . . . . . . ; командами

NOT_FOUND: . . . . ; нет. Обрабатываем вариант

. . . . . . . ; отсутствия совпадения

Вопрос: Какая команда должна быть выполнена перед меткой NOT_FOUND?

Остановимся еще на одной особенности команд обработки строк, которую мы до настоящего времени “замели под ковер”. Она связана с использованием дополнительного сегмента для размещения строки_приемника. Во-первых, описание этого сегмента отличается от основного сегмента данных только именем, но при его наличии нельзя забывать о назначении регистра ES:

DSEG SEGMENT PARA PUBLIC ‘DATA’

SOURCE DW 1,2,3,4,5, . . . . . и т.д., всего 100 слов

. . . . . . . .

ЕSEG SEGMENT PARA PUBLIC ‘DATA’

DEST DW 100 DUP (?)

CSEG SEGMENT PARA PUBLIC ‘CODE’

ASSUME CS:CSEG, DS:DSEG, SS:STACK,ES:ESEG

. . . . . . . .. . . . . . . . . . ..

CLD

LEA SI, SOURCE

LEA DI, ES:DEST

MOV CX, 100

REP MOVS DEST, SOURCE

В этом фрагменте следует обратить внимание на оператор загрузки адреса из дополнительного сегмента в регистр DI. Запись адреса ES:DEST содержит ссылку на полный адрес операнда в памяти ЭВМ: сегментную составляющую адреса в регистре ES и смещение относительно этой составляющей DEST. Такую запись следует применять для адресации любых данных из дополнительного сегмента данных.

Вообще-то ЭВМ можно “обмануть” и выполнять команды работы со строками, находящимися в одном сегменте данных, например, следующим образом:

DSEG SEGMENT PARA PUBLIC ‘DATA’

SOURCE DW 1,2,3,4,5, . . . . . и т.д., всего 100 слов

. . . . . . . .

DEST DW 100 DUP (?)

CSEG SEGMENT PARA PUBLIC ‘CODE’

ASSUME CS:CSEG, DS:DSEG, SS:STACK

. . . . . . . . . .

PUSH DS

POP ES

CLD

LEA SI, SOURCE

LEA DI, DEST

MOV CX, 100

REP MOVSW

В этом фрагменте в дополнительный сегментный регистр данных занесен тот же адрес, что и в основной сегментный регистр данных (через стек). Микропроцессор будет работать с сегментными регистрами DS и ES как обычно, даже не подозревая, что копирует данные, находящиеся в одном сегменте.

Теперь коротко о других командах работы со строками.

Команда сканирования SCAS осуществляет поиск в строке, которая индексируется через регистр DI и располагается в дополнительном сегменте данных. Поиск производится путем сравнения элементов строки с содержимым регистра_аккумулятора AL, если строка представляет совокупность байтов и регистра АХ, если строка представляет совокупность слов. Действие команды можно описать так:

Содержимое регистра_аккумулятора – содержимое очередного элемента строки.

Аналогично команде CMPS могут быть использованы префиксы повторения REPE / REPZ –поиск до первого несовпадения с образцом или REPNE / REPNZ – поиск до первого совпадения с образцом.

Команды загрузки используются для извлечения элемента из строки для дальнейшей обработки этого элемента (например, для его изменения). Используется команда в совокупности с командой сканирования в следующем контексте: “найти элемент строки по образцу и извлечь его для изменения” или в контексте: ”найти первое несовпадение в строке и напечатать не совпавший элемент”. Во 2-ом случае для поиска несовпадений используется команда CMPS. В команде LODS в качестве операнда используется источник – строка, индексируемая регистром SI, находящаяся в основном сегменте данных. Действие команды заключается в извлечении элемента, адресуемого парой регистров DS и SI и занесении этого элемента в регистр_аккумулятор AL, если строка представляет совокупность байтов и регистра АХ, если строка представляет совокупность слов. Префиксы для этой команды не нужны.

Команда сохранения STOS по своему действию противоположна команде LODS, т.е. она позволяет сохранить значение элемента из аккумулятора в строке. Действие команды заключается в занесении элемента из регистра_аккумулятора AL, если строка представляет совокупность байтов, или регистра АХ, если строка представляет совокупность слов, в приемник, адресуемый парой регистров ES и DI. Префиксы для этой команды могут понадобиться, а могут и не понадобиться, в зависимости от алгоритма обработки данных.


0282021959632083.html
0282090272305874.html
    PR.RU™