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

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

    Запланировано Прикреплена Закрыта Перенесена Взлом игр (начинающим)
    1 Сообщения 1 Posters 311 Просмотры
    Загружаем больше сообщений
    • Сначала старые
    • Сначала новые
    • По количеству голосов
    Ответить
    • Ответить, создав новую тему
    Авторизуйтесь, чтобы ответить
    Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
    • PromisingP
      Promising
      отредактировано Promising

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

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

      Регистры
      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
      • Первое сообщение
        Последнее сообщение