我破解了以下代码:
unsigned long long get_cc_time () volatile {
uint64 ret;
__asm__ __volatile__("rdtsc" : "=A" (ret) : :);
return ret;
}
它适用于g ++但不适用于Visual Studio。 我该如何移植它? 检测VS / g ++的正确宏是什么?
答案 0 :(得分:3)
#if defined(_MSC_VER)
// visual c
#elif defined(__GCCE__)
// gcce
#else
// unknown
#endif
我的内联汇编程序技能很生疏,但它的工作方式如下:
__asm
{
// some assembler code
}
但是只使用 rdtsc ,你可以使用内在函数:
unsigned __int64 counter;
counter = __rdtsc();
答案 1 :(得分:2)
VC ++中有一个_MSC_VER宏,在MSDN中被描述为“Microsoft特定”,并且可能在其他编译器上编译代码时未定义。您可以使用#ifdef来确定它是什么编译器,并为gcc和VC ++编译不同的代码。
#ifdef _MSC_VER
//VC++ version
#else
//gcc version
#endif
答案 2 :(得分:2)
直接使用RDTSC
指令有一些严重的缺点:
使用OS定时器接口更好,但仍可能有一些相同的缺点,具体取决于实现:
clock_gettime()
QueryPerformanceCounter()
另请注意,Microsoft Visual C ++在定位64位处理器时不支持内联汇编,因此Virne指出了__rdtsc()
内在函数。
答案 3 :(得分:2)
OP没有具体问题:我找到了一种定义适用于两种语法版本的宏的方法:
#ifdef _MSC_VER
# define ASM(asm_literal) \
__asm { \
asm_literal \
};
#elif __GNUC__ || __clang__
# define ASM(asm_literal) \
"__asm__(\"" \
#asm_literal \
"\" : : );"
#endif
不幸的是,因为预处理器strips newlines before macro expansion,你必须用这个宏包围每个汇编语句。
float abs(float x) {
ASM( fld dword ptr[x] );
ASM( fabs );
ASM( fstp dword ptr[x] );
return x;
}
但请注意GCC和clang use AT&T/UNIX assembly synax但是MSVC使用英特尔汇编语法(虽然找不到任何官方来源)。但幸运的是,GCC / clang也可以是configured to use Intel syntax。使用__asm__(".intel_syntax noprefix");
/ __asm__(".att_syntax prefix");
(确保重置更改,因为它会影响从该点生成的所有程序集,甚至是编译器从C源生成的那个) )。这将给我们留下这样一个宏:
#ifdef _MSC_VER
# define ASM(asm_literal) \
__asm { \
asm_literal \
};
#elif __GNUC__ || __clang__
# define ASM(asm_literal) \
"__asm__(\".intel_syntax noprefix\");" \
"__asm__(\"" \
#asm_literal \
"\" : : );" \
"__asm__(\".att_syntax prefix\");"
#endif
或者您也可以使用-masm=intel
标志使用GCC / clang进行编译,该标志会全局切换语法。