Например есть 8-байтная переменная - х с помощью команд сопроцессора (FPU) это можно сделать вот так Код (ASM): fild qword ptr х ; Загрузить целое число fstp qword ptr х ; Записать и вытолкнуть вещественное число а как это можно сделать командами блока - XMM кто в теме подскажите пожалуйста
я знал эту команду cvtsi2sd но она к сожалению не подходит перед тем как создать тему ради интереса решил посмотреть как это сделает мой - Microsoft Visual Studio 2013 unsigned __int64 fff; double ddd; ddd = fff; при дизасме выдал вот такой код: Код (ASM): mov edx,fff+4 mov ecx,fff call sub_4024CC movsd ddd,xmm0 ну и соответственно функцию к ней Код (ASM): sub_4024CC proc near test edx, edx jnz short loc_4024E5 cvtsi2sd xmm0, ecx shr ecx, 1Fh movsd xmm1, ds:qword_403280[ecx*8] addsd xmm0, xmm1 retn loc_4024E5: movd xmm4, ds:dword_4032F8 movd xmm5, ds:dword_4032FC movd xmm6, ds:dword_4032F4 movd xmm0, ecx movd xmm1, edx punpckldq xmm0, xmm1 mov eax, 20h bsr ecx, edx sub eax, ecx movd xmm2, eax psllq xmm0, xmm2 movdqa xmm3, xmm0 psllq xmm3, 33h psrlq xmm3, 33h movdqa xmm1, xmm3 psrlq xmm0, 0Dh psllq xmm0, 1 pcmpgtd xmm3, xmm4 punpckldq xmm3, xmm3 psubq xmm0, xmm3 pcmpgtd xmm1, xmm5 punpckldq xmm1, xmm1 psubq xmm0, xmm1 psubq xmm6, xmm2 psllq xmm6, 34h paddq xmm0, xmm6 retn sub_4024CC endp протестировав функцию я убедился в том что функция отрабатывает нормально но Visual Studio обычно старается делать оптимизированный код по этому я был сильно удивлён предложенным вариантом ведь код описанный мной выше Код (ASM): fild qword ptr fff ; Загрузить целое число fstp qword ptr ddd ; Записать и вытолкнуть вещественное число не только компактен но и сделает это гораздо быстрее
попробуйте другии студии, 2019, 2022 а также другие компиляторы - gcc, clang благо счас все есть онлайн например https://godbolt.org/
Если в программе использовать одновременно сопроцессор и see, тогда придется переключаться командами finit/emms. А эти команды выполняются гораздо дольше указанной функции.
теперь ради интереса решил посмотреть как это сделает - Dev-Cpp unsigned __int64 fff; double ddd; ddd = fff; при дизасме выдал вот такой код: Код (ASM): fild ds:fff fstp [ebp+var_28] ; используется стековый адрес памяти cmp dword ptr ds:fff+4, 0 jns short loc_4012DA fld ds:tbb ; глобальная константная лексема - tbb dt 1.8446744073709551616e19 fld [ebp+var_28] faddp st(1), st fstp [ebp+var_28] loc_4012DA: fld [ebp+var_28] fstp ds:ddd после анализа я понял почему Visual Studio или Dev-Cpp так делают это по тому что после определённого 8-байтного значения - fff код: Код (ASM): fild fff ; Загрузить целое число fstp ddd ; Записать и вытолкнуть вещественное число на выходе даёт не правильный результат Visual Studio и Dev-Cpp проверяют старшиий (dword) 8-байтного значения и если он не ноль применяют дополнительный алгоритм я конечно могу ошибаться но тестами я выявил что максимальное значение при котором дополнительный алгоритм не нужен это значение - 7fffffffffffffffh и только начиная со значения - 8000000000000000h нужно применить дополнительный алгоритм я пересобрал и упростил код выданный - Dev-Cpp Код (ASM): .const tbb dt 1.8446744073709551616e19 .code fild fff fstp ddd cmp byte ptr fff+7,80h jb ??1 fld tbb fld ddd faddp st(1),st fstp ddd ??1: вроде бы работает как надо