内联装配问题

时间:2011-05-12 11:44:08

标签: c++ visual-c++ gcc intel inline-assembly

我尝试使用 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 ,但在遇到内联汇编后,它在内部错误方面失败了。

我该怎么办?

2 个答案:

答案 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找到文档。