Перейти к содержанию

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


Рекомендуемые сообщения

В данном руководстве описано как использовать xmm регистры, а так же некоторые команды.
 

Список некоторых команд (напоминалка):
 

Спойлер

Регистры
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 наше число
addss xmm0,[MyAddValue] //Добавляем к нему другое
movss [MyLabel],xmm0 //Записываем из xmm0 назад в число.

Так же нужно помнить что регистры это не стек, и потому значения свои сохраняют после записи.

Как уже было сказано выше, эти регистры могут содержать целых 4 элемента - работа с массивами:
Массив должен состоять из четырёх элементов, например такой:

MyMassiv:
dd (float)2
dd (float)7
dd (float)29324.126
dd (float)8261.3

Что бы записать этот массив в xmm мы можем использовать следующий код:

movups xmm0,[MyMassiv]

После чего получим в xmm0 все четыре числа по порядку.
Теперь мы можем сделать что нибудь с этим массивом, например умножить его на другой массив. К примеру вот такой:

MyMassivMul:
dd (float)1
dd (float)2
dd (float)0.5
dd (float)2

Умножаем:

movups xmm0,[MyMassiv] //Загружаем наш массив
movups xmm1,[MyMassivMul] //Загружаем массив на который умножим
mulps xmm0,xmm1 //Умножаем
movups [MyMassiv],xmm0 //Возвращаем в наш массив.

После выполнения этого кода, массив примет такой вид:
2; 14; 14662,063; 16522,6.
Так же можно вычитать, делить, находить корень, складывать, и многое другое.

Изменено пользователем inaginary
  • Понравилось 1
  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

22 минуты назад, Garik66 сказал:

Пример

В статье нет примеров и видео, поскольку мне кажется тут не о чем больше рассказывать, (в отличии от FPU) ?

Ссылка на комментарий
Поделиться на другие сайты

24 минуты назад, inaginary сказал:

В статье нет примеров и видео, поскольку мне кажется тут не о чем больше рассказывать, (в отличии от FPU) ?

Ты пока не много сталкивался с пользователями,
некоторым приходится ну очень подробно рассказать и показать.:wacko:
ЗЫ: даже то, что я одинаковые лейблы сделал, могут не обратить внимания, и потом задавать вопросы.

 

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, Garik66 сказал:

некоторым приходится ну очень подробно рассказать и показать

 

 таким  как я . )))))
у меня появлиась  сразу куча вопросов .  полезная инфа , но много не  понятно

  • Смешно 1
Ссылка на комментарий
Поделиться на другие сайты

  • 1 год спустя...
  • 2 месяца спустя...
  • 1 год спустя...

Как-то так?

Спойлер

spacer.png

Получается... если вам нужно изменить значение в xmm2 регистре, допустим 3-е (0,94) это будет так.

asd:
dd (float)0
dd (float)0.34
dd (float)999.90
dd (float)0

P.S. статья очень полезная... 

Спойлер

особенно если внимательно прочитать.

 Спасибо!

Изменено пользователем Xanxasa222
Уточнение.
Ссылка на комментарий
Поделиться на другие сайты

Спасибо! Статья помогла при взломе скорости перемещения игрока в игре Not The Time For Dragons.

Дело в том что при перемещение ГГ к координатам прибавляется N-ое число. Все три координаты записаны в одном регистре и число что к ним прибавляется тоже в одном.

Получился такой скрипт. Всё работает.

Спойлер
[ENABLE]
aobscanmodule(MovementSpeed,thegame.exe,0F ? ? ? ? 0F ? ? ? ? F3 ? ? ? ? ? F3 ? ? ? 8B ? ? ? ? ? 0F)
alloc(newmem,$1000)
label(code)
label(return)
registersymbol(code)
registersymbol(MovementSpeed)

newmem:
  movaps xmm1,[esp+60] // original xmm2 пуст =0
  movups xmm2,[code]  
  mulps xmm1,xmm2
  xorps xmm2,xmm2
  jmp return

code:
dd (float)4  //множитель координаты Y
dd (float)1  //множитель координаты Z мне её не нужно умножать
dd (float)4  //множитель координаты X
dd (float)1  //какоето левое число =1

MovementSpeed:
  jmp newmem
return:

[DISABLE]
MovementSpeed:
db 0F 28 4C 24 60
unregistersymbol(*)
dealloc(newmem)
{
// ORIGINAL CODE - INJECTION POINT: thegame.exe+4C06D
thegame.exe+4C036: B8 01 00 00 00           - mov eax,00000001
thegame.exe+4C03B: 88 83 01 13 00 00        - mov [ebx+00001301],al
thegame.exe+4C041: EB 07                    - jmp thegame.exe+4C04A
thegame.exe+4C043: C6 83 01 13 00 00 00     - mov byte ptr [ebx+00001301],00
thegame.exe+4C04A: A1 A0 24 09 01           - mov eax,[thegame.exe+C924A0]
thegame.exe+4C04F: 8B 90 A0 00 00 00        - mov edx,[eax+000000A0]
thegame.exe+4C055: 0F AF 90 94 00 00 00     - imul edx,[eax+00000094]
thegame.exe+4C05C: F3 0F 2A C2              - cvtsi2ss xmm0,edx
thegame.exe+4C060: 8B 90 A4 00 00 00        - mov edx,[eax+000000A4]
thegame.exe+4C066: 0F AF 90 98 00 00 00     - imul edx,[eax+00000098]
// ---------- INJECTING HERE ----------
thegame.exe+4C06D: 0F 28 4C 24 60           - movaps xmm1,[esp+60]
// ---------- DONE INJECTING  ----------
thegame.exe+4C072: 0F 58 4C 24 50           - addps xmm1,[esp+50]
thegame.exe+4C077: F3 0F 11 44 24 20        - movss [esp+20],xmm0
thegame.exe+4C07D: F3 0F 2A C2              - cvtsi2ss xmm0,edx
thegame.exe+4C081: 8B 90 A8 00 00 00        - mov edx,[eax+000000A8]
thegame.exe+4C087: 0F AF 90 9C 00 00 00     - imul edx,[eax+0000009C]
thegame.exe+4C08E: 8B 45 0C                 - mov eax,[ebp+0C]
thegame.exe+4C091: F3 0F 11 44 24 24        - movss [esp+24],xmm0
thegame.exe+4C097: F3 0F 2A C2              - cvtsi2ss xmm0,edx
thegame.exe+4C09B: F3 0F 11 44 24 28        - movss [esp+28],xmm0
thegame.exe+4C0A1: F3 0F 10 05 D8 C1 9A 00  - movss xmm0,[thegame.exe+5AC1D8]
}

 

 

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.