В процессе обучения я начал экспериментировать с инструкциями AVX и написал простое умножение массивов, чтобы все работало, очень просто. Первой проблемой было заполнение xmm0 и xmm1, поскольку nasm не принимает XMMWORD в качестве размера (yasm принимает его, но так как он больше не разрабатывается, я предпочитаю его не использовать), мне пришлось заполнять его двумя 64-битными шагами. Я нашел эту ветку , показывающую решение, которое работает для меня, используя MOVQ и PINSRQ. Код, который (вроде) работает:
section .data
array1: dd 1.0, 2.0, 3.0, 4.0 ; Declares 2 arrays of 16 bytes
array2: dd 2.0, 3.0, 4.0, 5.0
section .text
global _start
_start:
mov r8, qword array1 ; Stores the address of the 1st element
mov r9, qword array2 ; of each array in the registers
movq xmm0, r8 ; Populates the first half of xmm0
pinsrq xmm0, r8, 1 ; Populates the second half
movq xmm1, r9 ; The same for xmm1
pinsrq xmm1, r9, 1
vmulps xmm0, xmm1 ; Multiplies the arrays and save in xmm0
xor ebx, ebx
mov rax, 1
int 80h
Но прежде чем я нашел это решение, я пытался с:
vmovlps xmm0, qword [r8]
vmovhps xmm0, qword [r8 + 8]
Они должны заполнить младшие биты, а затем старшиебиты регистра xmm0, но программа вылетает в первый вмов. Итак, вы, ребята, можете объяснить, почему эта пара mov не работает, а пара movq / pinsrq работает нормально? Не стесняйтесь также давать советы, если есть что-то, что можно улучшить в этом простом процессе.
========= РЕДАКТИРОВАТЬ, ОБНОВИТЬ ========
И просто для того, чтобы попытаться поместить результат обратно в память, чтобы rdi указывал на первое из 4 32-битных значений, хранящихся в xmm0, на случай, если я захочу вернуть rdi, он собирается, но вывод (выводимый программой C ++)фигня, так что это явно неверный путь:
vmulps xmm0, xmm1 ; Multiplies the arrays and save in xmm0
vmovdqa [rdi], xmm0 ; Assembles and doesn't crash, but no meaningful result