开发者

Inline assembly troubles

I tried to compile with GCC inline assembly code which compiled fine with MSVC, but got the following errors for basic operations:

// 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
}

After looking through documentation covering the topic, I found out that I should probably convert (even if I am only interested in x86) Intel style assembly code to AT&T style. However, after trying to use AT&T style I got even more weird errors:

mov var, %edx //error: Expected primary-expression before % token
mov $var, edx //error: label 'LASM$$s' used but not de开发者_StackOverflow中文版fined

I should also note that I tried to use LLVM-GCC, but it failed miserably with internal errors after encountering inline assembly.

What should I do?


For Apple's gcc you want -fasm-blocks which allows you to omit gcc's quoting requirement for inline asm and also lets you use Intel syntax.

// test_asm.c

int main(void)
{
    int var;

    __asm__
    {
        mov edx,var
        push ebx
        sub esp,8
    }

    return 0;
}

Compile this with:

$ gcc -Wall -m32 -fasm-blocks test_asm.c -o test_asm

Tested with gcc 4.2.1 on OS X 10.6.


g++ inline assembler is much more flexible than MSVC, and much more complicated. It treats an asm directive as a pseudo-instruction, which has to be described in the language of the code generator. Here is a working sample from my own code (for MinGW, not 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 ;
  }

You can find documentation at http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜