Łuk*_*Lew 5 c++ assembly cross-platform
我破解了以下代码:
unsigned long long get_cc_time () volatile {
uint64 ret;
__asm__ __volatile__("rdtsc" : "=A" (ret) : :);
return ret;
}
Run Code Online (Sandbox Code Playgroud)
它适用于 g++,但不适用于 Visual Studio。我怎样才能移植它?检测 VS/g++ 的正确宏是什么?
#if defined(_MSC_VER)
// visual c
#elif defined(__GCCE__)
// gcce
#else
// unknown
#endif
Run Code Online (Sandbox Code Playgroud)
我的内联汇编技能很生疏,但它的工作原理是:
__asm
{
// some assembler code
}
Run Code Online (Sandbox Code Playgroud)
但是只使用rdtsc你可以只使用内在函数:
unsigned __int64 counter;
counter = __rdtsc();
Run Code Online (Sandbox Code Playgroud)
http://msdn.microsoft.com/en-us/library/twchhe95.aspx
OP 的具体问题放在一边:我找到了一种方法来定义一个适用于两种语法版本的宏:
#ifdef _MSC_VER
# define ASM(asm_literal) \
__asm { \
asm_literal \
};
#elif __GNUC__ || __clang__
# define ASM(asm_literal) \
"__asm__(\"" \
#asm_literal \
"\" : : );"
#endif
Run Code Online (Sandbox Code Playgroud)
不幸的是,因为预处理器在宏扩展之前去掉换行符,所以你必须用这个宏包围每个汇编语句。
float abs(float x) {
ASM( fld dword ptr[x] );
ASM( fabs );
ASM( fstp dword ptr[x] );
return x;
}
Run Code Online (Sandbox Code Playgroud)
但请注意 GCC 和 clang使用 AT&T/UNIX 汇编语法,但 MSVC 使用 Intel 汇编语法(虽然找不到任何官方来源)。但幸运的是 GCC/clang 也可以配置为使用 Intel 语法。要么使用__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
Run Code Online (Sandbox Code Playgroud)
或者,您也可以使用-masm=intel全局切换语法的标志使用 GCC/clang 进行编译。