Пишу программу по переводу 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;
}