Cамоучитель по Assembler

         

CMPS Сравнение строк


CMPSB Сравнение строк по байтам

CMPSW Сравнение строк по словам


Команды предназначены для операций над строками (строкой называется последовательность байтов или слов памяти с любым содержимым). Они сравнивают по одному элементу каждой строки, фактически осуществляя вычитание второго операнда из первого и устанавливая в соответствии с результатом вычитания флаги CF, PF, AF, ZF, SF и OF. Команда cmpsb выполняет сравнение по байтам, команда cmpsw - по словам, а команда cmps может быть использована для сравнения как байтов, так и слов. В последнем случае размер сравниваемых элементов определяется их описанием (с помощью директив db или dw). Первый операнд адресуется через DS:SI, второй - через ES:DI. Таким образом, операцию сравнения можно условно изобразить следующим образом:


(DS:SI) - (ES:DI) -> флаги процессора


После каждой операции сравнения регистры SI и DI получают положительное (если флаг DF=0) или отрицательное (если флаг DF=1) приращение. Величина приращения составляет 1 или 2 в зависимости от размера сравниваемых элементов (байт или слово).
Вариант команды cmps имеет формат


cmps строка_1, строка_2


(что не избавляет от необходимости инициализировать регистры DS:SI и ES:DI адресами строк строка_1 и строка_2 соответственно). В этом формате возможна замена сегмента первой строки:


cmps ES:строка_ 1, строка_2


Рассматриваемые команды могут предваряться префиксами повторения repe/repz (повторять, пока элементы равны, т.е. до первого неравенства) и repne/repiiz (повторять, пока элементы не равны, т.е. до первого равенства). В любом случае выполняется не более СХ операций над последовательными элементами.
После выполнения рассматриваемых команд регистры SI и DI указывают на ячейки памяти, находящиеся за теми (если DF=0) или перед теми (если DF=1) элементами строк, на которых закончились операции сравнения.

Пример


;В полях данных сегмента данных, адресуемого через DS:
strl db 'FILE.001' ;1-я строка
;В полях данных сегмента данных, адресуемого через ES:
str2 db 'FILE.012' ;2-я строка
;В программном сегменте:
eld ;Сравнение вперед
mov SI,offset strl ;DS:SI ® strl
mov DI, off set str2 ;ES:DI ® str2
mov CX,8 ;Длина сравниваемых строк
repe cmpsb ;Поиск различия в строках
je equal ;Переход, если строки
;совпадают
notequ: ;Продолжение, если строки
;не совпадают


В примере 1 строки не совпадают, и команда je выполнена не будет. После завершения сравнения строк управление будет передано на метку notequ. Содержимое регистров в этой точке: СХ=1 (так как не выполнено сравнение одной последней пары символов), SI = <смещение strl> + 7, DI = <смещение strl> + 7 (выполнено сравнение 7 пар символов).

Пример


;В полях данных сегмента данных, адресуемого через DS:
strl db '12345678*90' ;1-я строка
;В полях данных сегмента данных, адресуемого через ES:
str2 db ' abcdefgh*ij' ;2-я строка
; В программном сегменте:
cld ;Сравнение вперед
mov SI,offset strl;DS:SI ' strl
mov DI,offset str2;ES:DI ' str2
mov CX,11 ;Длина сравниваемых строк
repne cmpsb ;Поиск первой пары
;одинаковых элементов
jne notequ ;Переход, если таковой нет
found: ;Продолжение, если пара
;одинаковых элементов найдена

В примере 2 имеется пара одинаковых элементов (*) в позиции 8 от начата строк. Поэтому команда jne выполнена не будет. После завершения сравнения строк управление будет передано на метку found. Содержимое регистров в этой точке: СХ=2 (так как не выполнено сравнение двух последних пар символов), SI = <смещение strl> + 9, DI = <смешенис strl> + 9 (выполнено сравнение 9 пар символов).

Пример


;В полях данных сегмента, адресуемого через ES:
strl db '09.12.1998' ;1-я строка
str2 db '09.12.1998' ;2-я строка
;В программном сегменте:
eld ;Сравнение вперед
mov SI, off set strl ;DS:SI -> strl
mov DI,offset str2 ;ES:DI -> str2
mov CX,10 ;Длина сравниваемых строк
repe cmps ES:str1,ES:str2 ;Поиск различия в строках
je equal ; Переход, если строки
;одинаковы
notequal: ;Продолжение, строки
;различаются


В примере 3 строки одинаковы и после завершения сравнения управление будет передано на метку equal. Поскольку строки описаны с помощью директив db, фактически выполняется команда cmpsb, т.е. побайто вое сравнение.


Пример



;В полях данных сегмента, адресуемого через DS
areal dd 152345,168666,954333
area2 dd 152345,168666,954331
;B программном сегменте
push DS
pop ES ;ES=DS
mov SI,offset areal ;DS:SI ->areal
mov DI,offset area2 ;ES:DI ->area2
mov CX,3 ;Будем сравнивать З числа
repe cmpsd
je equal

В приведенном примере в строках (фактически это целочисленные массивы) различаются последние элементы, и команды jc выполнена не будет.





Содержание раздела