• Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
  • Зарегистрироваться
  • Войти
GameHackLab[RU]
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
  • Зарегистрироваться
  • Войти

О MMX и SSE - некоторые команды, регистры

Запланировано Прикреплена Закрыта Перенесена Взлом игр (начинающим)
1 Сообщения 1 Posters 310 Просмотры
Загружаем больше сообщений
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • P
    Promising
    отредактировано Promising 2 нояб. 2023 г., 14:01 11 февр. 2023 г., 13:21

    В этой теме показаны примеры использования регистров и команд:

    Список некоторых команд (не всех, их очень много):

    Регистры
    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

    1 ответ Последний ответ Ответить Цитировать 6
    1 из 1
    • Первое сообщение
      1/1
      Последнее сообщение