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

Сравнение значений double.


Гость Пыль

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

 

В 16.08.2020 в 18:29, Пыль сказал:

Как сравнивать значения с типом данных double?

если я не ошибаюсь то можно сделать так:

1) записываешь свое дабл число в скрипте через dq (double) //твое число

2) сохраняешь дабл из регистра со смещением в свободный регистр

3) сравниваешь свое число с значение регистра cmp qword ptr [твой дабл],сохраненный регистр

Примерчик:

Спойлер

label(code)
label(my_double)
label(return)

newmem:
  push rbx
  mov rbx, [rcx+12]
  cmp qword ptr [my_double],rbx
  pop rbx
code:
  rol byte ptr [rcx+00],00
  add [rax],al
  jmp return
my_double:
  dq (double)50000
INJECT:
  jmp newmem
  nop
return:
registersymbol(INJECT)

 

 

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

1 час назад, FENIX145 сказал:

cmp qword ptr

Так лучше не сравнивать дробные числа. Их нужно сравнивать с указанием точности. Например, юзеру нужно сравнить два числа 99. В одном случае это 99.1 а в другом - 99.2. В этом случае числа не будут равны, а юзеру было бы достаточно точности до целых.

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

у мееня вопрос похожий  поэтому спрошу здесь .

как правильно  сравнить число  с знаком  в 64 бит ?  у меня получаеться , что когда сравнение  числа например FFFF000000000001 прыжок jg не срабатывает как если  бы это число отрицательное .

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

33 минуты назад, Alex2411 сказал:

как правильно  сравнить число  с знаком  в 64 бит ? 

сам пытаюсь сейчас разобраться и меня отправили читать https://ru.m.wikipedia.org/wiki/Дополнительный_код. Надеюсь тебе поможет эта информация, а я в свою очередь передал эстафетную палочку :D  Ну и дальше после получения нужного представления нужно будет сравнить через cmp qword ptr. За информацию благодарить @Xipho

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

1 час назад, Alex2411 сказал:

у мееня вопрос похожий  поэтому спрошу здесь .

как правильно  сравнить число  с знаком  в 64 бит ?  у меня получаеться , что когда сравнение  числа например FFFF000000000001 прыжок jg не срабатывает как если  бы это число отрицательное .

Я выходил из этого положения - делая два сравнения по 4 байта в HEX

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

Всё можно сравнить с помощью fpu, в этом нету никаких сложностей, просто команды загрузки разные.
Вот например сравнение двух double чисел:
 

Спойлер

//В [label] хранится double 200, а в [label+8] хранится double 2
//Будем всё загружать, что бы не было сложностей с пониманием если числа изначально не с плавяющей запятой, но 8 байт
//Предположим что у нас rax занят, и его нельзя портить

push rax //сохраняем rax (eax если 32 бит)
fld qword [label] //Загрузить в стек fpu double число (qword) без преобразований (fld), теперь оно в st(0)
fld qword [label+8] //Загрузить второе число, теперь в стеке 2 числа (2 и 200), теперь оно в st(0), а первое в st(1)
fcomp st(0), st(1) //Сравнить число 2 с числом 200, и убрать из стека число 2 (fcomp)
fstp st(0) //Убрать оставшееся число из стека, что бы он стал чистым.
fstsw ax //Поместить флаги fpu в регистер ax (который часть eax, который часть rax)
sahf //Загрузить флаги из регистра во флаги cpu
pop rax //восстанавливаем rax (eax если 32 бит)
//Нужно заметить что после этого нельзя использовать операторы сравнения которые основаны на незагруженных флагах, то есть нельзя использовать jl или jg, вместо них нужно использовать jb и ja
ja metka //прыжок куда нужно

 


Если нужно сравнить не double числа, а float, то qword нужно заменить на dword, а если нужно сравнить числа 8 байт без плавающей запятой, тогда нужно заменить команды на вот такие:
 

Спойлер

{ В этом примере сравниваются 2 разных числа, одно int64, а второе float32, занимающие 8 и 4 байта. 
Для сравнения float загружается без изменений (fld), и указанием размера 4 байта (dword), 
а int64 загружается с преобразованием (в число с плавающей запятой, fild), и размером 8 байт (qword). 
Понимая эти параметры, используя код снизу можно сравнить любые числа, просто меняя их. }
//В [label] integer64 число 97, в [label+8] float число 7

push rax //сохраняем rax (eax если 32 бит)
fild qword [label] //Загрузить в стек fpu int64 число (qword) с преобразованием! (fild), теперь оно в st(0)
fld dword [label+8] //Загрузить второе, но уже float, (dword) без преобразований (fld) число, теперь в стеке 2 числа (7 и 97)
fcomp st(0), st(1) //Сравнить число 7 с числом 97, и убрать из стека число 7 (fcomp)
fstp st(0) //Убрать оставшееся число из стека, что бы он стал чистым.
fstsw ax //Поместить флаги fpu в регистер ax (который часть eax, который часть rax)
sahf //Загрузить флаги из регистра во флаги cpu
pop rax //восстанавливаем rax (eax если 32 бит)

ja metka //прыжок куда нужно

 


С помощью этого примера можно сравнивать любые числа любых доступных размеров и типов просто изменяя команды в нём.

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

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

Я выходил из этого положения - делая два сравнения по 4 байта в HEX

 

это долго и  не удобно . я то же  делаю несколько шагов .  проверяю  отрицательное число или нет , а потом сравниваю , но я думал может  есть простая  комнада сравнения с знаком  за один шаг  как в 32 бит.

 

9 часов назад, imaginary сказал:

fcomp st(0), st(1) //Сравнить число 7 с числом 97, и убрать из стека число 7 (fcomp) fstp st(0) //Убрать оставшееся число из стека, что бы он стал чистым. fstsw ax //Поместить флаги fpu в регистер ax (который часть eax, который часть rax) sahf //Загрузить флаги из регистра во флаги cpu

 

объясни пожлста  почему ты тут  не применяешь  команды fcompp или fcomip ? fcompp выталкнет сразу  два числа стека ,  а fcomip  ставит сразу  обычные флаги  вместо fpu. мне кажеться  так быстрее получиться . 

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

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

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

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