СМР Сравнение
Сами операнды не изменяются. Таким образом, если команду сравнения записать в общем виде
стр операнд_1, операнд_2
то ее действие можно условно изобразить следующим образом:
операнд_1 - операнд_2 -> флаги процессора
В качестве первого операнда команды
сmр можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве
второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение,
однако не допускается определять оба операнда одновременно, как ячейки памяти.
Операнды могут быть байтами или словами и представлять числа со знаком или без
знака. Обычно вслед за командой сmр стоит одна из команд условных переходов,
анализирующих состояние флагов процесс
сора. При сравнении чисел без знака необходимо использовать команды условных
переходов, предназначенные для анализа чисел без знака
(ja, jb и проч.). При
сравнении чисел со знаком необходимо использовать команды условных переходов,
предназначенные для анализа чисел со знаком
(jl, jg и проч.).
Пример 1
cmp АХ,10000 ;АХ-10000
je eqlOOOO ;Переход на метку eql0000,
;если АХ=10000
Пример 2
;В полях данных:
base dw 8002h
;В программном сегменте:
cmp DX,base DX-base
jb below ;Переход на метку below,
;если DX, рассматриваемое
;как число без знака, меньше
;числа без знака 8002h=32770
Пример 3
;В полях данных:
base dw 8002h
;В программном сегменте:
cmp DX,base DX-base
jl less ;Переход на метку less, если
;DX, рассматриваемое как
;число со знаком, меньше
;числа со знаком 8002h=-32766
Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров.
Пример
cmp EAX,8000000 Oh
ja above ;Переход, если
;EAX=80000001h...FFFFFFFFh
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) элементами
строк, на которых закончились операции сравнения.
Пример 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 пар символов).
Пример 2
;В полях данных сегмента данных, адресуемого через 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 пар символов).
Пример 3
;В полях данных сегмента, адресуемого через 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, т.е. побайто вое сравнение.
Допустимо использование 32-битовых операндов и дополнительных режимов
адресации 32-разрядных процессоров.
386+ CMPSD Сравнение строк по двойным словам
Команда аналогична командам МП 86 cmpsb и cmpsw, но позволяет сравнивать 32-битовые
участки строк, адресуемых через регистры DS:ESI и ES:EDI (или, в 16-разрядных
приложениях, через DS:SI и ES:DI). Использование мнемоники cinpsd с префиксом
rep не означает, что в качестве счетчика будет автоматически использоваться
расширенный регистр ЕСХ.
Пример
;В полях данных сегмента, адресуемого через 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 выполнена не будет.