18. ЦЕЛЫЕ ЧИСЛА ВМЕСТО ЧИСЕЛ С ПЛАВАЮЩЕЙ ТОЧКОЙ
==============================================
Целочисленные инструкции, обычно, исполняются быстрее, чем инструкции с
плавающей точкой, так что выгоднее использовать целочисленные инструкции для
замены простых инструкций с плавающей точкой. Наиболее очевидный пример -
перемещение данных. Пример:
FLD QWORD PTR [ESI] / FSTP QWORD PTR [EDI]
Заменяется на:
MOV EAX,[ESI] / MOV EBX,[ESI+4] / MOV [EDI],EAX / MOV [EDI+4],EBX
Если первый код исполняется за 4 такта, то последний за 2.
Проверка числа с плавающей точкой на равенство нулю:
В данном случае значение числа с плавающей точкой, обычно, представлено
32 или 64 битовой нулевой последовательностью, но здесь надо быть осторожным:
бит знака может быть установлен! Минус ноль считается корректным числом, и
процессор действительно может с генерировать такое число, например умножая
отрицательное число на ноль. Таким образом, если вы хотите сравнить число
с плавающей точкой с нулем, то вы не должны тестировать бит знака. Пример:
FLD DWORD PTR [EBX] / FTST / FNSTSW AX / AND AH,40H / JNZ IsZero
Используя целочисленные инструкции и опуская бит знака получим:
MOV EAX,[EBX] / ADD EAX,EAX / JZ IsZero
Таким образом вместо 9 тактов предыдущего кода мы опять получили 2 такта.
Если число с плавающей точкой двойной точности (QWORD), то вам надо
протестировать биты 32-62. Если они установлены в ноль и младшая половина
тоже ноль, то все нормально.
Проверка отрицательности:
Число с плавающей точкой отрицательное, если у него установлен бит знака и
есть, по крайней мере, еще один установленный бит. Например:
MOV EAX,[NumberToTest] / CMP EAX,80000000H / JA IsNegative
Манипулирование с битом знака.
Вы можете изменить знак числа с плавающей точкой, просто флипнув бит знака.
Пример:
XOR BYTE PTR [a] + (TYPE a) - 1, 80H
Таким же образом, вы, можете получить модуль число с плавающей точкой, просто
применив AND.
Сравнение чисел:
Числа с плавающей точкой хранятся в уникальном формате, который позволяет
вам использовать целочисленные инструкции для их сравнение, исключая бит
знака. Если вы уверены, что оба числа с плавающей точкой нормальные(коррект-
ные? прим. переводчика) и положительные, то вы можете их просто сравнить как
целые числа. Пример:
FLD [a] / FCOMP [b] / FNSTSW AX / AND AH,1 / JNZ ASmallerThanB
Заменить на:
MOV EAX,[a] / MOV EBX,[b] / CMP EAX,EBX / JB ASmallerThanB
Этот метод позволяет сравнить два числа с плавающей точкой, если вы уверены,
что оба числа имеют одинаковую точность и не отрицательные.
Если возможны отрицательные числа, то вы должны два дополнения и сделать
занкозначимое сравнение:
MOV EAX,[a]
MOV EBX,[b]
MOV ECX,EAX
MOV EDX,EBX
SAR ECX,31 ; копируем бит знака
AND EAX,7FFFFFFFH ; удаляем бит знака
SAR EDX,31
AND EBX,7FFFFFFFH
XOR EAX,ECX ; делаем 2 дополнения, если бит знака установлен
XOR EBX,EDX
SUB EAX,ECX
SUB EBX,EDX
CMP EAX,EBX
JL ASmallerThanB ; знакозначимое сравнение
Этот метод работает только для нормальных(корректных? прим. переводчика) чисел
с плавающей точкой, включая -0.
Дальше
|