На главную Назад
Добро пожаловать, уважаемый посетитель!

Две оставшиеся строковые команды используются в программах для

сравнения строковой информации.Первая из них - команда,

сканирование строки SCAS.Эта команда сравнивает значение в

регистре AL или регистре AX с операндом в памяти, на который

ссылается пара регистров ES:DI.Команда SCAS устанавливает флаги

нуля, переноса и переполнения, показывая результат сравнения

аккумулятора и ячейки памяти, и изменяет регистр DI так, чтобы он

указывал на следующий операнд в строке.

 

Команда SCAS не может использовать обычный префикс REP для

сканирования длинной строки информации. Точно так же, как команда

REP LODS не имеет смысла, команда REP SCAS не позволяет программе

контролировать каждое сравнение. Вместо этого существует два

варианта префикса REP - "повторять пока равно" REPE и "повторять

пока не равно" REPNE. Как и в случае обычного префикса REP,

программа загружает в регистр CX длину строки. Если указан префикс

REPE, команда выполняется ло тех пор, пока содержимое регистра AL

(или AX) не перестанет совпадать с ячейками памяти, или пока

содержимое регистра CX не станет равно 0. Пока аккумулятор

совпадает с ячейкой памяти, сканирование продолжается. Команда

REPNE в точности противоположна команде REPE. Сканирование

продолжается до тех пор, пока аккумулятор не совпадает с ячейкой

памяти.

 

Комбинация команд SCAS и REPNE позволяет программе выполнять

быстрый поиск по таблице. Чтобы найти объект в таблице, программа

должна перебрать каждую ячейку для сравнения с аргументом. На

Фиг. 4.24 показано, как команда SCAS выполняет эту функцию. В

регистре AL содержится аргумент сравнения. Таблица SCAN_TABLE

содержит значения, среди которых ведется поиск, а в регистре CX

находится длина таблицы. Команда REPNE SCASB сканирует таблицу до

тех пор, пока содержимое аккумулятора не станет равно элементу

строки. В этом месте регистр DI указывает на байт таблицы,

непосредственно следующий за сравнением. Вы можете определить

смещение совпавшего объекта, вычитая единицу из регистра DI после

метки FOUND. Программа может использовать эту информацию для

доступа к другой таблице, или таблицам, которые содержат

информацию, соответствующую этим исходным данным. Нужно обратить

особое внимание на команду JE после команды сканирования.

Существуют два случая, в которых управление передается этой

команде: байт в строке совпал с регистром AL и условие, задаваемое

префиксом REPNE, больше не выполняется; либо регистр CX достиг

нулевого значения без нахождения соответствующего числа в таблице.

В некоторых случаях создаются ситуации, исключающие появление

второго условия. Но в большинстве программ, необходимо учитывать

возможность неверных исходных данных. Программа перейдет на метку

FOUND после команды сканирования, если команда установила флаг нуля

(или равенства). Тем самым гарантируется, что сравнение найдено.

Если же регистр CX достиг нуля, последняя итерация сканирования

сбросила флаг нуля, показывая, что соответствия нет.

Microsoft (R) Macro Assembler Version 5.00 1/1/80 04:01:36

Фиг. 4.24 Поиск в таблице Page1-1

 

 

PAGE,132

TITLEФиг. 4.24 Поиск в таблице

0000CODESEGMENT

ASSUMECS:CODE,DS:CODE,ES:CODE

 

;--------------------------------------

; Поиск значения AL в таблице

;--------------------------------------

 

00008D 3E 000C RLEADI, SCAN_TABLE; Адрес таблицы

0004B9 000B 90MOVCX, SCAN_TABLE_LENGTH; Длина таблицы

0008F2/ AEREPNESCASB; Поиск

000A74 00JEFOUND; Если равно, то значение найдено

; ...; Иначе значение не найдено

000CFOUND:

;-----продолжение программы

 

000C89 96 93 8A 85 8D 83SCAN_TABLEDB'ЙЦУКЕНГШЩЗХ'

98 99 87 95

 

= 000BSCAN_TABLE_LENGTHEQU$-SCAN_TABLE

 

0017CODEENDS

END

 

Фиг. 4.24 Сканирование таблицы

Последняя строковая команда - сравнение строк CMPS. Подобно

сканированию строки, это - команда сравнения. Подобно команде MOVS,

она работает с двумя операндами памяти. Команда CMPS сравнивает

строку по адресу DS:SI со строкой по адресу ES:DI, и соответственно

устанавливает флаги. Как и для команды SCAS, в данном случае

использовать префикс REP нельзя, а префиксы REPE и REPNE можно

использовать беспрепятственно.

Microsoft (R) Macro Assembler Version 5.001/1/80 04:01:41

Фиг. 4.25 Сравнение строкPage 1-1

 

PAGE,132

TITLEФиг. 4.25 Сравнение строк

0000CODESEGMENT

ASSUMECS:CODE,DS:CODE,ES:CODE

 

;--------------------------------------

; Сравнивается 5-символьная строка с таблицей

; таких 5-символьных строк. Выход из программы

; если найдена искомая строка в таблице строк.

;--------------------------------------

 

0000FIG4_25 PROCNEAR

00008D 36 001D R LEASI, ARGUMENT; Адрес строки

00048D 3E 0022 R LEADI, COMPARE_TABLE; Адрес таблицы

0008BB 0000MOVBX, 0; В BX cчетчик просмотренных строк

000BCOMPARE_LOOP:

000B56PUSHSI; Сохранение адреса строки

000C57PUSHDI; Сохранение адреса таблицы

000DB9 0005MOVCX, 5; Сравниваются 5 байт

0010F3/ A6REPECMPSARGUMENT,COMPARE_TABLE; Сравнение

00125FPOPDI; Восстановление

00135EPOPSI;регистров

001474 06JEFOUND; Искомая строка найдена

001683 C7 05ADDDI, 5; Сдвиг указателя на следующую

;строку в таблице

001943INCBX; Номер текущей строки в таблице

001AEB EFJMPCOMPARE_LOOP; Цикл

 

001CFOUND:

001CC3RET

001DFIG4_25 ENDP

 

001D41 42 43 44 45ARGUMENTDB'ABCDE'

0022COMPARE_TABLELABELBYTE

002251 57 45 52 54 50 4F DB'QWERT','POIUY','ASDFG','LKJHG'

49 55 59 41 53 44 46

47 4C 4B 4A 48 47

00365A 58 43 56 42 4D 4E DB'ZXCVB','MNBVC','VWXYZ','ABCDE'

42 56 43 56 57 58 59

5A 41 42 43 44 45

004ACODEENDS

END

 

Фиг. 4.25 Сравнение строк

Фиг. 4.25 демонстрирует пример использования команды CMPS.

Этот пример сравнивает пятисимвольную исходную строку с таблицей

строк символов. Программа пытается найти соответствие исходной

строки с элементом таблицы. Когда строка найдена, в регистре BX

нахолится индекс строки. В программе используется префикс REPE, так

что команда сравненния строк выполняется до тех пор, пока один из

символов аргумента не совпадает с символом таблицы. Если все пять

символов совпали, программа находит правильный элемент. Команда JE

("переход, если равно") проверяет результат команды CMPS. Если

сравнение завершилось из=за несоответствия символов, флаг нуля

показывает ненулевое состояние. Если же команда CMPS завершилась

потому, что счетчик CX стал нулевым, флаг нуля покажет совпадение и

произойдет переход на метку FOUND. Вы можете заметить, что в этом

примере отсутствуют некоторые необходимые детали, которые смогли бы

сделать его хорошей программой. Например, он никак не обрабатывает

случай, когда исходная строка не совпала ни с одним элементм

таблицы. Любой хороший программист скажет вам, что исключительные

ситуации нужно обрабатывать всегда.


 

Mail.ru