我尝试使用 GCC 内联汇编代码进行编译,该代码使用 MSVC 编译良好,但基本操作出现以下错误:
// var is a template variable in a C++ function
__asm__
{
mov edx, var //error: Register name not specified for %edx
push ebx //error: Register name not specified for %ebx
sub esp, 8 //error: Register name not specified for %esp
}
在查看了涵盖该主题的documentation之后,我发现我应该将英特尔样式汇编代码转换为 AT& T 强烈的>风格。但是,在尝试使用 AT& T 样式后,我遇到了更多奇怪的错误:
mov var, %edx //error: Expected primary-expression before % token
mov $var, edx //error: label 'LASM$$s' used but not defined
我还应该注意,我尝试使用 LLVM-GCC ,但在遇到内联汇编后,它在内部错误方面失败了。
我该怎么办?
答案 0 :(得分:3)
对于Apple的gcc,您需要-fasm-blocks
,它允许您省略gcc对内联asm的引用要求,并允许您使用Intel语法。
// test_asm.c
int main(void)
{
int var;
__asm__
{
mov edx,var
push ebx
sub esp,8
}
return 0;
}
用以下内容编译:
$ gcc -Wall -m32 -fasm-blocks test_asm.c -o test_asm
在OS X 10.6上使用gcc 4.2.1进行测试。
答案 1 :(得分:2)
g ++内联汇编程序比MSVC更灵活,更复杂。它将asm指令视为伪指令,必须用代码生成器的语言进行描述。这是我自己的代码(适用于MinGW,而不是Mac)的工作示例:
// int BNASM_Add (DWORD* result, DWORD* a, int len)
//
// result += a
int BNASM_Add (DWORD* result, DWORD* a, int len)
{
int carry ;
asm volatile (
".intel_syntax\n"
" clc\n"
" cld\n"
"loop03:\n"
" lodsd\n"
" adc [edx],eax\n"
" lea edx,[edx+4]\n" // add edx,4 without disturbing the carry flag
" loop loop03\n"
" adc ecx,0\n" // Return the carry flag (ecx known to be zero)
".att_syntax\n"
: "=c"(carry) // Output: carry in ecx
: "d"(result), "S"(a), "c"(len) // Input: result in edx, a in esi, len in ecx
) ;
return carry ;
}
您可以在http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm找到文档。