Справочник по языку Ассемблера IBM PC



Команда cmps - часть 2



Существует возможность еще больше конкретизировать информацию о причине, приведшей к окончанию операции сравнения. Сделать это можно с помощью команд условной передачи управления (табл. 1 и 2).

Таблица 1. Сочетание команд условной передачи управления с результатами команды cmps (для чисел со знаком)

Причина прекращения операции сравнения Команда условного перехода, реализующая переход по этой причине
операнд_источник > операнд_приемник jg
операнд_источник = операнд_приемник je
операнд_источник <> операнд_приемник jne
операнд_источник < операнд_приемник jl
операнд_источник <= операнд_приемник jle
операнд_источник >= операнд_приемник jge

Таблица 2. Сочетание команд условной передачи управления с результатами команды cmps (для чисел без знака)

Причина прекращения операции сравнения Команда условного перехода, реализующая переход по этой причине
операнд_источник > операнд_приемник ja
операнд_источник = операнд_приемник je
операнд_источник <> операнд_приемник jne
операнд_источник < операнд_приемник jb
операнд_источник <= операнд_приемник jbe
операнд_источник >= операнд_приемник jae

Как определить местоположение очередных совпавших или не совпавших элементов в цепочках?

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


Для получения истинного адреса этих элементов необходимо скорректировать содержимое индексных регистров, увеличив либо уменьшив значение в них на длину элемента цепочки.


В качестве примера рассмотрим программу из листинга 2, которая сравнивает две строки, находящиеся в одном сегменте. Используется команда cmps. Префикс повторения - repe.

 Листинг 2. Сравнение двух строк командой cmps <1> ;prg_11_2.asm <2> MODEL       small <3> STACK       256 <4> .data <5> match       db      0ah,0dh,'Строки совпадают.','$' <6> failed      db      0ah,0dh,'Строки не совпадают','$' <7> string1     db      '0123456789',0ah,0dh,'$';исследуемые строки <8> string2     db      '0123406789','$' <9> .code <10> ASSUME     ds:@data,es:@data       ;привязка DS и ES к сегменту данных <11> main: <12>    mov     ax,@data        ;загрузка сегментных регистров <13>    mov     ds,ax <14>    mov     es,ax   ;настройка ES на DS <15> ;вывод на экран исходных строк string1 и string2 <16>    mov     ah,09h <17>    lea     dx,string1 <18>    int     21h <19>    lea     dx,string2 <20>    int     21h <21> ;сброс флага DF — сравнение в направлении возрастания  адресов <22>    cld <23>    lea     si,string1      ;загрузка в si смещения string1 <24>    lea     di,string2      ;загрузка в di смещения string2 <25>    mov     cx,10   ;длина строки для префикса repe <26> ;сравнение строк (пока сравниваемые элементы строк равны) <27> ;выход при обнаружении не совпавшего элемента <28> cycl: <29>    repe    cmps    string1,string2 <30>    jcxz    equal   ;cx=0, то есть строки совпадают <31>    jne     not_match       ;если не равны — переход на not_match <32> equal:             ;иначе, если совпадают, то <33>    mov     ah,09h  ;вывод сообщения <34>    lea     dx,match <35>    int     21h <36>    jmp     exit    ;выход <37> not_match:         ;не совпали <38>    mov     ah,09h <39>    lea     dx,failed <40>    int     21h     ;вывод сообщения <41> ;теперь, чтобы обработать не совпавший элемент в  строке, необходимо уменьшить значения регистров si и di <42>    dec     si <43>    dec     di <44> ;сейчас в ds:si и es:di адреса несовпавших элементов <45> ;здесь вставить код по обработке несовпавшего элемента <46> ;после этого продолжить поиск в строке: <47>    inc     si <48>    inc     di <49>    jmp     cycl <50> exit:      ;выход <51>    mov     ax,4c00h <52>    int     21h <53> end        main    ;конец программы

Программа достаточно прозрачна, только два момента, на мой взгляд, требуют пояснения:

во-первых, строки 42 и 43, в которых мы скорректировали адреса очередных элементов для получения адресов несовпавших элементов. Вы должны понимать, что если сравниваются цепочки с элементами слов или двойных слов, то корректировать содержимое esi/si и edi/di нужно на 2 и 4 байта соответственно;

во-вторых, строки 47–49. Смысл их в том, что для просмотра оставшейся части строк необходимо установить указатели на следующие элементы строк за последними несовпавшими. После этого можно повторить весь процесс просмотра и обработки несовпавших элементов в оставшихся частях строк. 




Содержание  Назад  Вперед