О MMX и SSE - некоторые команды, регистры
-
В этой теме показаны примеры использования регистров и команд:
Список некоторых команд (не всех, их очень много):
Регистры xmm0 xmm1 xmm... xmm15 Выполняют те же функции что и обычные регистры, но могут хранить в разы больше. Могут быть приёмником и источником для команд MMX. Команды записи movd *,* - записывает 4 байта из переменной в приёмник. movq *,* - записывает 8 байт. movss *,* - записываем float (4 байта) из переменной в приёмник movsd *,* - записывает doble (8 байт) их переменной в приёмник Массивные movups *,* - записывает 4 элемента массива в том порядке в котором они идут в приёмник movaps *,* - записывает выравненные 4 элемента массива movhlps *,* - записываем 2 левых элемента из источника в 2 правых приёмника movlhps *,* - записываем 2 правых элемента из источника в 2 левых приёмника movhps *,* - записывает 2 левых элемента из источника в 2 левых приёмника. movlps *,* - то же что и выше но 2 правых элемента. Арифметические команды. Любые действия выполняются в следующем порядке - приёмник на источник, запись в приёмник. (приёмник это первая *, источник - вторая *) addsd *,* - сложение двух чисел с плавающей запятой, типа doble (8 байт). subsd *,* - то же что выше но вычитание. mulsd *,* - Умножение. divsd *,* - Деление. sqrtsd *,* - Корень из doble addss *,* - Сложение двух float (4 байта) subss *,* - Вычитание float mulss *,* - Умножение float divss *,* - Деление float sqrtss *,* - Корень из float Массивные addps *,* - складывает 2 массива subps *,* - вычитает массив из массива divps *,* - делит массив на массив. mulps *,* - умножает массив на массив. sqrtps *,* - корни из массива Команды сравнения comiss - сравнение двух float comisd - сравнение doble Команды преобразования cvtsi2ss - преобразовать целое в float cvtsi2sd - преобразовать целое в doble cvttss2si - преобразовать вещественное в целое с округлением.
Регистры в этих дополнениях сопроцессора очень похожи на основные, но в отличии от них могут содержать целых четыре элемента, и даже работать сразу со всеми четырьмя!
Все функции сложения, вычитания, и другие могут быть совершены только с регистрами.
Такая инструкция
addss xmm0,[MyLabel]
сработает:
А такаяaddss [MyLabel],xmm0
- нет.Потому следует все операции производить с регистрами.
Например, если необходимо прибавить что нибудь к переменной можно использовать такой код:movss xmm0,[MyLabel] //Записываем в xmm0 число из label addss xmm0,[MyAddValue] //Добавляем к нему другое movss [MyLabel],xmm0 //Записываем из xmm0 назад в label.
Помните что регистры это не стек, и потому значения свои сохраняют после записи.
Эти регистры могут содержать целых 4 элемента, позволяя обрабатывать списки из четырёх значений:
Список должен состоять из четырёх элементов, например такой:MyList: dd (float)2 dd (float)7 dd (float)29324.126 dd (float)8261.3
Что бы записать этот список в xmm мы можем использовать инструкцию
movups xmm0,[MyList]
.После чего получим в
xmm0
все четыре числа по порядку.
Теперь мы можем сделать что нибудь с этим массивом, например умножить его на другой массив"MyListMul: dd (float)1 dd (float)2 dd (float)0.5 dd (float)2
Умножение:
movups xmm0,[MyList] //Загружаем умножаемый список movups xmm1,[MyListMul] //Загружаем умножающий список mulps xmm0,xmm1 //Умножаем movups [MyList],xmm0 //Возвращаем в умножаемый список.
После выполнения этого кода, список примет такой вид:
2 14 14662,063 16522,6
Так же можно вычитать, делить, находить корень, складывать, и многое другое.
Не используйте
movaps
если не знаете выравнен ли адрес, проверить это можно разделив адрес на 16, он должен делиться без остатка. Используйтеmovups
разница по скорости минимальная для простых одиночных операций.Imaginary