Иллюстрированный самоучитель по Assembler

       

CMPXCHG Сравнение и обмен


Команда cmpxchg выполняет в одной операции сравнение и обмен операндов. Команда требует два параметра и неявным образом использует третий операнд - регистр ЕАХ. Первый операнд (приемник) должен находиться в 16- или 32-битовой ячейке памяти, второй операнд (источник) - в регистре общего назначения такого же размера. Команда выполняет сравнение операнда-приемника с содержимым неявного операнда - регистра ЕАХ. Если сравниваемые значения совпадают, операнд-приемник замещается операндом-источником (т.е. содержимое регистра записывается в память). Если сравниваемые значения не совпадают, содержимое памяти (приемник) поступает в регистр ЕАХ (рис. П1). Команда воздействует на флаги OF, SF, ZF, AF, PF и CF.

Рис.П1. Действие команды cmpxchg

Пример 1

; В полях данных

mem dw 135

; В программном сегменте

mov AX,135

mov BX,60

cmpxchg mem,BX ;mem=AX. Регистр ® память ;

mem=60, BX=60, АХ=135

Пример 2

; В полях данных



mem dw 135

;В программном сегменте

mov AX,148

mov BX,60

cmpxchg mem,BX ;mem<>AX. Память ® АХ

;mem=135, BX=60, AX=148

Pentium+ CMPXCHG8B Сравнение и обмен 8 байтов

Команда cmpxchgSb выполняет в одной операции сравнение и обмен 8-байтовых операндов. Команда требует один параметр и неявным образом использует еще два операнда - пары регистров EDX:EAX и ЕСХ:ЕВХ. В качестве явного операнда команды (приемника) может выступать только 64-битная (8-байтовая) ячейка памяти. Команда выполняет сравнение операнда-приемника в памяти с содержимым EDX:EAX. Если сравниваемые значения совпадают, то операнд-приемник в памяти замещается 64-битным значением ЕСХ:ЕВХ. Если сравниваемые значения не совпадают, содержимое памяти поступает в пару регистров EDXrEAX, замещая один из сравниваемых операндов (рис. П2). Команда воздействует на флаг ZF.

Рис. П2. Действие команды cmpxchg8b

Пример 1

; В полях данных

mem dq 1122334455667788h

;В программном сегменте

mov ЕСХ,9

mov ЕВХ,5

mov EDX,11223344h

mov EAX,55667788h

cmpxchgSb mem ;mem=EDX:EAX. ECX:EBX ® mem ;


mem=0000000900000005h
Пример 2
; В полях данных

mem dq 1122334455667788h

;B программном сегменте

mov ECX,9

mov EBX,5

mov EDX,11223344h

mov EAX,55667789h

cmpxchgSb mem ;memOEDX: EAX. Mem -" EDX : EAX ;mem=1122334455667788h ;EDX=11223344h, EAX=55667788h

При работе с многобайтовыми данными не следует забывать о том, что в памяти байты любых данных всегда выстраиваются в порядке их номеров, т.е. от младшим к все более старшим, в то время как при изображении чисел мы применяем обратный порядок - сначала пишем старшие разряды числа, затем младшие. В то же время символьные строки мы изображаем так же, как они располагаются в памяти - для нас естественно считать, что по мере движения по строке вправо номер символа возрастает.
Пример 3
; В полях данных

meml db '12345678' ;Строка-операнд

mem2 db '12345678' ;Сравниваемая строка

;В программном сегменте

mov ECX,68676665h ;'efgh'

mov EBX,64636261h ;'abcd'

mov EDX,dword ptr mem2+4 ;Забираем старшую

;часть строки

mov EAX,dword ptr mem2 ;Забираем младшую

;часть строки

cmpxchg8b gword ptr meml ;Операнды совпадают

;ZF=1, mem1=''abcdefgh''

;ECX:EBX без изменений

;EDX:EAX без изменений
Пример 4
;В полях данных

meml db '12345678' ;Строка-операнд

mem2 db 'abcdefgh' ;Сравниваемая строка

; В программном сегменте

mov ECX,68676665h ;'efgh'

mov EBX,64636261h ;'abed'

mov EDX,dword ptr mem2+4 ;3абираем старшую

;часть строки

mov EAX,dword ptr mem2 ;Забираем младшую

;часть строки

cmpxchg8b qword ptm mem1 ;Операнды не совпадают

;ZF=0, EDX=38373635='5678'

;EAX=34333231='1234'

;mem1s без изменения

;При неравенстве ЕСХ:ЕВХ не принимают участие в операции
Pentium+ CPUID Идентификация процессора
Команда cpuid позволяет получить код идентификации процессора, установленного на данном компьютере. Команда в качестве неявного операнда использует регистр ЕАХ. Для процессоров Pentium регистр ЕАХ перед вызовом команды cpuid может принимать два значения: 0 и 1. Если ЕАХ=0, то команда возвращает в регистре ЕАХ код 1, а в регистрах ЕВХ, EDX и ЕСХ (именно в таком порядке) - три части символьной строки, идентифицирующей изготовителя процессора. Для процессоров Intel возвращаемая строка в целом имеет вид "Genumclatcl".


Если перед вызовом команды cpuid значение ЕАХ равно 1, то команда возвращает в регистре ЕАХ коды разработки конкретной версии процессора, а в регистре EDX код IBFli, содержащий информацию о возможностях процессора.

Коды разработки в регистре ЕАХ хранятся в следующем формате:
биты 0 ... 3 - номер поколения (например, 3);
биты 4 ... 7 - модель (например, 4);
биты 8 ... 11 - семейство (5 для Pentium).
Содержимое регистра EDX включает конфиденциальную информацию изготовителя, а также говорит о наличии на кристалле микропроцессора арифметического сопроцессора (бит 0) и поддержке команды cmpxchgSb (бит 8).
Пример
;В полях данных mem dd 0,0,0 ;В программном сегменте

mov ЕАХ,О

cpuid ;EAX=0001h

mov mem, ЕВХ

mov mem+4, EDX

mov mem+8, ECX ;mem='Genuinelntel'

cpuid EAX=543h (например) ,EDX = lBFh
CWD Преобразование слова в двойное слово
Команда cwd заполняет регистр DX знаковым битом содержимого регистра АХ, преобразуя тем самым 16-разрядное число со знаком в 32-разрядное, размещаемое в регистрах DX:AX. Команду удобно использовать для преобразования двухбайтового делимого в четырехбайтовое (двойное слово) при делении на 16-разрядный операнд. Команда не имеет параметров и не воздействует на флаги процессора.
Пример 1
mov AX,32767 ;AX=7FFFh

cwd ;AX=7FFFh, DX=OOOOh.

;DX:AX=32767
Пример 2
mov AX,-32768 ;AX=8000h

cwd ;AX=8000h, DX=FFFFh.

;DX:AX=-32768
386+ CWDE Преобразование слова в двойное слово с расширением
Команда cwde заполняет старшую половину регистра ЕАХ знаковым битом содержимого регистра АХ, преобразуя тем самым 16-разрядное число со знаком в 32-разрядное, размещаемое в расширенном регистре ЕАХ. Команда не имеет операндов и не воздействует на флаги процессора.
Пример
; В полях данных

mem dw - 3

;В программном сегменте

mov AX,mem ;AX=FFFD

cwde ;EAX=FFFFFFFDh

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