Сравнение целых чисел

Последнее обновление: 03.07.2023

Инструкции (v)pcmpeqb, (v)pcmpeqw, (v)pcmpeqd, (v)pcmpeqq, (v)pcmpgtb, (v)pcmpgtw, (v)pcmpgtd и (v)pcmpgtq сравнивают байты, числа word, dword или qword в соответствующих дорожках операндов. Результат сравнения сохраняется в первом операнде.

Инструкции pcmpeqX, сравнивают на равенство соответственно два байта, два слова, два двойных и два четверных слова из соответствуюших дорожек.

pcmpeqb xmmdest, xmmsrc/mem128 ; сравнивает 16 байтовых дорожек
pcmpeqw xmmdest, xmmsrc/mem128 ; сравнивает 8 дорожек с числами word
pcmpeqd xmmdest, xmmsrc/mem128 ; сравнивает 4 дорожек с числами dword
pcmpeqq xmmdest, xmmsrc/mem128 ; сравнивает 2 дорожек с числами qword

Инструкции устанавливают значение всех битов 1, если два значения в одной дорожке равны. Если значения не равны, то устанавливается 0 для всех бит. Например:

.data
    nums0 dword 1, 2, 4, 8 
    nums1 dword 1, 2, 3, 4
.code
main proc 
    movaps xmm0, nums0 
    movaps xmm1, nums1
    pcmpeqd xmm0, xmm1       ; XMM0 = XMM0 == XMM1
    ; XMM0 = -1, -1, 0, 0
    ret
main endp
end

Здесь сравниваются соответствуюшие элементы векторов из XMM0 и XMM1, которые представляют числа dword. Поскольку первые два элемента обоих векторо равны, а последние два не равны, то в результате получим вектор FFFFFFFFh, FFFFFFFFh, 0, 0

Инструкции pcmpgtX проверят, больше первый операнд чем второй:

pcmpgtb xmmdest, xmmsrc/mem128 ; сравнивает байты в 16 дорожках
pcmpgtw xmmdest, xmmsrc/mem128 ; сравнивает числа word в 8 дорожках
pcmpgtd xmmdest, xmmsrc/mem128 ; сравнивает числа dword в 4 дорожках
pcmpgtq xmmdest, xmmsrc/mem128 ; сравнивает числа qword в 2 дорожках

Инструкции устанавливают значение всех битов 1, если значение из первого операнда больше значения из второго. Иначе устанавливается 0 для всех бит. Например:

.data
    nums0 dword 0, 2, 4, 5
    nums1 dword 0, 1, 2, 7 
.code
main proc 
    movaps xmm0, nums0 
    movaps xmm1, nums1
    pcmpgtd xmm0, xmm1       ; XMM0 = XMM0 > XMM1
    ; XMM0 = 0, -1, -1, 0
    ret
main endp
end

128-варианты инструкций vpcmpeqX и vpcmpgtX работают аналогично SSE-инструкциям, только сравнивают второй и третий операнды и результат помещают в первый операнд.

vpcmpeqb xmmdest, xmmsrc1, xmmsrc2/mem128 ; сравнивает байты в 16 дорожках
vpcmpeqw xmmdest, xmmsrc1, xmmsrc2/mem128 ; сравнивает числа word в 8 дорожках
vpcmpeqd xmmdest, xmmsrc1, xmmsrc2/mem128 ; сравнивает числа dword в 4 дорожках
vpcmpeqq xmmdest, xmmsrc1, xmmsrc2/mem128 ; сравнивает числа qword в 2 дорожках

vpcmpgtb xmmdest, xmmsrc1, xmmsrc2/mem128 ; сравнивает байты в 16 дорожках
vpcmpgtw xmmdest, xmmsrc1, xmmsrc2/mem128 ; сравнивает числа word в 8 дорожках
vpcmpgtd xmmdest, xmmsrc1, xmmsrc2/mem128 ; сравнивает числа dword в 4 дорожках
vpcmpgtq xmmdest, xmmsrc1, xmmsrc2/mem128 ; сравнивает числа qword в 2 дорожках

256-разрядные варианты инструкций vpcmpeqX и vpcmpgtX сравнивают в два раза больше дорожек в 256-битных операндах:

vpcmpeqb ymmdest, ymmsrc1, ymmsrc2/mem256 ; сравнивает байты в 32 дорожках
vpcmpeqw ymmdest, ymmsrc1, ymmsrc2/mem256 ; сравнивает числа word в 16 дорожках
vpcmpeqd ymmdest, ymmsrc1, ymmsrc2/mem256 ; сравнивает числа dword в 8 дорожках
vpcmpeqq ymmdest, ymmsrc1, ymmsrc2/mem256 ; сравнивает числа qword в 4 дорожках

vpcmpgtb ymmdest, ymmsrc1, ymmsrc2/mem256 ; сравнивает байты в 32 дорожках
vpcmpgtw ymmdest, ymmsrc1, ymmsrc2/mem256 ; сравнивает числа word в 16 дорожках
vpcmpgtd ymmdest, ymmsrc1, ymmsrc2/mem256 ; сравнивает числа dword в 8 дорожках
vpcmpgtq ymmdest, ymmsrc1, ymmsrc2/mem256 ; сравнивает числа qword в 4 дорожках

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

(v)pmovmskb

Инструкция (v)pmovmskb позволяет проверить результат сравнения. Она извлекает старший бит из всех байтов в регистре XMM или YMM и сохраняет 16 или 32 бита (соответственно) в регистре общего назначения. Эта инструкция устанавливают все старшие биты регистра общего назначения в 0 (помимо тех, которые необходимы для хранения битов маски):

pmovmskb reg, xmm
vpmovmskb reg, xmm
vpmovmskb reg, ymm

Первым операндом инструкции является 32- или 64-битный регистр общего назначения.

Инструкция (v)pmovmskb копирует знаковые биты из каждой байтовой дорожки в соответствующую битовую позицию регистра общего назначения. Так, она копирует бит 7 из регистра XMM (бит знака для дорожки 0) в бит 0 регистра назначения; она копирует бит 15 из регистра XMM (бит знака для дорожки 1) в бит 1 регистра назначения, бит 23 из регистра XMM (бит знака для дорожки 2) в бит 2 регистра назначения и так далее.

128-битные инструкции заполняют только биты с 0 по 15 регистра назначения (обнуляя все остальные биты). 256-битная форма инструкции vpmovmskb заполняет биты с 0 по 31 целевого регистра (при использовании 64-битного регистра все остальные биты обнуляются)

Можно использовать инструкцию pmovmskb для извлечения одного бита из каждой байтовой дорожки в регистре XMM или YMM после инструкций (v)pcmpeqb или (v)pcmpgtb.

.data
    nums0 byte 0, 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43
    nums1 byte 0, 0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 55, 34, 21, 13
.code
main proc 
    movdqa xmm0, oword ptr nums0 
    movdqa xmm1, oword ptr nums1
    pcmpgtb xmm0, xmm1       ; XMM0 = XMM0 > XMM1
    pmovmskb eax, xmm0
    ret
main endp
end

После выполнения этой программы бит 0 EAX будет равен 1 или 0, если байт 0 XMM0 был равен или не равен байту 0 XMM1 соответственно. Аналогично, бит 1 EAX будет содержать результат сравнения байта 1 XMM0 с XMM1 и т. д. вплоть до бита 15, который хранит результат сравнивнения байтов из дорожек 15 регистров XMM0 и XMM1.

Проблема этой инструкции заключается в том, что она работает только для байтов, для число word/dword/qword аналогичных инструкций нет. Однако используя логические операции сдвига и умножения/сложения, мы можем определить необходимую логику.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850