Загрузка в регистры константных значений

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

Расширения SSE/AVX не поддерживают загрузку в регистры XMM/YMM константных значений, например, числовых литералов. В качестве решения мы, конечно, можно определить переменную с нужным значением и затем использовать одну из инструкций, например, movdqa для загрузки переменной в регистр XMM/YMM.

.data
    num word 11
.code
main proc 
    movdqu xmm0, oword ptr num  ; загружаем данные
    ret
main endp
end

Но это не самый быстрый путь. В качестве альтернативы можно применять различные комбинации логических, арифметических операций и операций сравнения. Посмотрим возможные варианты.

Вначала загружаем в один регистр число 0. Для этого используем операцию XOR с помощью инструкции pxor:

pxor xmm0, xmm0     ; XMM0 = 0

Чтобы установить все биты в регистре XMM или YMM в 1, можно использовать инструкцию pcmpeqb

pcmpeqb xmm1, xmm1     ; XMM1 = -1

Так как любой регистр XMM или YMM равен самому себе, эта инструкция сохраняет 0FFh во всех байтах XMM1.

Например, чтобы получить 1, мы можем вычесть из 0 число -1:

pxor xmm0, xmm0
pcmpeqb xmm1, xmm1
psubb xmm0, xmm1    ; 0 - (-1) = 1

Здесь применяется вычитание байтов с помощью инструкции psubb, но аналогично можно применять инструкции psubw или psubd для получения 16- или 32-битного результата

Если необходимо получить другое число, то можно использовать, например, инструкцию pslld. Например, если вы хотите загрузить в регистр XMM0 значение 8080808080808080h, вы можете использовать следующую последовательность инструкций:

pxor xmm0, xmm0
pcmpeqb xmm1, xmm1
psubb xmm0, xmm1
pslld xmm0, 7       ; сдвигаем 01h на 4 разряда влево, получаем 80h в каждом байте

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

Для загрузки 2n – 1 (когда все биты вплоть до n-го бита в числе равны 1) можно применять следующий способ:

; для 16-битных дорожек
pcmpeqd xmm0, xmm0
psrlw xmm0, 16 - n  ; Очищаем правые 16 - n бит в xmm0

; для 32-битных дорожек
pcmpeqd xmm0, xmm0
psrld xmm0, 32 - n  ; Очищаем правые 32 - n бит в xmm0

; для 64-битных дорожек
pcmpeqd xmm0, xmm0 
psrlq xmm0, 64 - n      ; Очищаем правые 64 - n бит в xmm0

Подобным образом можно сдвигать влево:

; для 16-битных дорожек
pcmpeqd xmm0, xmm0
psllw xmm0, n       ; сбрасываем левые n бит в xmm0

; для 32-битных дорожек
pcmpeqd xmm0, xmm0 
pslld xmm0, n       ; сбрасываем левые n бит в xmm0

; для 64-битных дорожек
pcmpeqd xmm0, xmm0
psllq xmm0, n       ; сбрасываем левые n бит в xmm0

Например, загрузим в XMM1 число 7:

pcmpeqd xmm1, xmm1
psrld xmm1, 32 - 3      ; XMM1 = 7

Здесь сдвигаем двойное слово (32-битное число) на 29 разрядов влево, то есть остается 3 разряда, которые равны 111 или 7 в десятичной.

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