Пишу программу по переводу HEX в DOUBLE и FLOAT и наоборот для Mac Os Mavericks (признаюсь честно, прихоть препода). Проблема состоит в том, что когда я делаю это при помощи ассемблера, то не получается переводить хекс во флоат, остальные функции работают, а здесь я всё не могу понять в чём проблема. Прошу сразу учесть, что в ассемблере уровень моих знаний довольно низок, поэтому я буду очень рад различным разъяснениям.
Версии:
Mac OS X Mavericks 10.9.4
gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
Код:
Код:
#include <iostream>
#include <cstring>
#include <string>
using namespace std
enum
{
CMD_FLOAT_TO_HEX,
CMD_DOUBLE_TO_HEX,
CMD_HEX_TO_FLOAT,
CMD_HEX_TO_DOUBLE,
CMD_EXIT
}
template<typename in, typename out>
out Asm1(in n) // FLOAT / DOUBLE -> HEX
{
out res
asm volatile
(
"fldl %1;"
"fstpl %0;"
: "=m" (res) : "m" (n)
)
return res
}
double Asm2(long long n) // HEX -> DOUBLE
{
double res
asm volatile
(
"movsd %%xmm0, %[n]\n\t;"
"movsd %0, %%xmm0\n\t;"
: [n] "=m" (n), "=r" (res)
)
return res
}
float Asm3(int n) // HEX -> FLOAT
{
float res
asm volatile
(
"movsl %%xmm0, %[n]\n\t;"
"movsl %0, %%xmm0\n\t;"
: [n] "=m" (n), "=r" (res)
)
return res
}
template<typename in, typename out>
inline out Memcpy(in n)
{
out res
memcpy(&res, &n, sizeof(in))
return res
}
template<typename in, typename out>
inline out Cast(in n)
{
return *reinterpret_cast<out*>(&n)
}
template<typename in, typename out>
inline out Union(in n)
{
union
{
in _n
out _res
}
_n = n
return _res
}
int main()
{
int n
cout << "<0> - float to hex" << endl
cout << "<1> - double to hex" << endl
cout << "<2> - hex to float" << endl
cout << "<3> - hex to double" << endl
cout << "<4> - exit" << endl << endl
do
{
cout << "choose command (from 0 to 4): "
cin >> n
cout << endl
switch (n)
{
case CMD_FLOAT_TO_HEX:
float f1
cout << "write a number: "
cin >> f1
cout << "\na float number " << f1 << " in hex:\t0x" << hex << Memcpy<float, int>(f1) << " (MEMCPY)" << endl
cout << "\t\t\t\t0x" << hex << Cast<float, int>(f1) << " (REINTERPRETER_CAST)" << endl
cout << "\t\t\t\t0x" << hex << Union<float, int>(f1) << " (UNION)" << endl
cout << "\t\t\t\t0x" << hex << Asm1<float, int>(f1) << " (__ASM) "<<endl
cout << endl
break
case CMD_DOUBLE_TO_HEX:
double d1
cout << "write a number: "
cin >> d1
cout << "\na double number " << d1 << " in hex:\t0x" << hex << Memcpy<double, long long>(d1) << " (MEMCPY)" << endl
cout << "\t\t\t\t0x" << hex << Cast<double, long long>(d1) << " (REINTERPRETER_CAST)" << endl
cout << "\t\t\t\t0x" << hex << Union<double, long long>(d1) << " (UNION)" << endl
cout << "\t\t\t\t0x" << hex << Asm1<double, long long>(d1) << " (__ASM) " << endl
cout << endl
break
case CMD_HEX_TO_FLOAT:
uint32_t f2
cout << "write a hex: "
cin >> hex >> f2
cout << "\na hex 0x" << hex << f2 << " is equal to float\t" << Memcpy<int, float>(f2) << " (MEMCPY)" << endl
cout << "\t\t\t\t\t" << Cast<int, float>(f2) << " (REINTERPRETER_CAST)" << endl
cout << "\t\t\t\t\t" << Union<int, float>(f2) << " (UNION)" << endl
cout << "\t\t\t\t\t" << Asm3(f2) << " (__ASM) " << endl
cout << endl
break
case CMD_HEX_TO_DOUBLE:
uint64_t d2
cout << "write a hex: "
cin >> hex >> d2
cout << "\na hex 0x" << hex << d2 << " is equal to double\t" << Memcpy<long long, double>(d2) << " (MEMCPY)" << endl
cout << "\t\t\t\t\t\t" << Cast<long long, double>(d2) << " (REINTERPRETER_CAST)" << endl
cout << "\t\t\t\t\t\t" << Union<long long, double>(d2) << " (UNION)" << endl
cout << "\t\t\t\t\t\t" << Asm2(d2) << " (__ASM) " << endl
cout << endl
break
case CMD_EXIT:
break
default:
cout << "wrong command" << endl
cout << endl
break
}
} while (n != CMD_EXIT)
return 0
}