将GCC / ATT样式汇编程序转换为visual studio汇编程序?

时间:2014-12-28 17:24:57

标签: c++ gcc assembly

我试图重写此代码段以在visual studio中工作,但我显然不明白如何使用冒号的目的和__volatile__的含义,

你能提供一些帮助吗?)?

__asm__ __volatile__ (
    "mov %0, %%edi\n"
    "xor %%eax, %%eax\n"
    "xor %%ecx, %%ecx\n"
    "dec %%ecx\n"
    "repne scasb\n"
    "sub %%ecx, %%eax\n"
    "dec %%eax\n"
:
: "m" (src)
: "memory", "%ecx", "%edi", "%eax");

谢谢!

2 个答案:

答案 0 :(得分:2)

两个内联汇编程序完全不同。 Visual Studio内联汇编程序更原始但更易于使用。在VS:

  • 内联汇编语言不需要用字符串括起来;
  • 指令操作数以dest,src顺序;
  • 按原样访问C / C ++变量;

你的代码没有任何输出操作符(在第一个冒号之后),所以我不知道它是如何产生任何影响的。但是假设eax寄存器最后要保存在src变量中。那你想要这样的东西:

char* src;
...
__asm {
    mov   edi,src
    xor   eax,eax
    xor   ecx,ecx
    dec   ecx
    repne scasb
    sub   eax,ecx
    dec   eax

    mov   src,eax    // save result
}

顺便说一下,它对我来说看起来不是最理想的。如果我正确理解了代码,那么eax的所有业务都可以由not ecx完成:

__asm {
    mov   edi,src
    xor   al,al
    xor   ecx,ecx
    dec   ecx
    repne scasb
    not   ecx

    mov   src,ecx    // save result
}

答案 1 :(得分:0)

  

......我不明白......冒号的目的......

Columbo在评论中指出,这是相关的手册页:6.43.2 Extended Asm - Assembler Instructions with C Expression Operands。冒号只是在ASM块中分隔标记。它们类似于分号终止C语句(或者更确切地说,可能是逗号运算符,因为它们是相关的)。

要重申页面的内容,一般格式为:

asm (
        Instructions (Assembler Code)
        : Outputs (C variables modified by the instructions)
        : Inputs (C expressions read by the instructions)
        : Clobbers (Registers or other values changed by the instructions)
    )

有时在分号之间不会有任何标记。例如,这就是内存屏障的样子:

__asm__ __volatile__ ("" ::: "memory")

没有汇编代码,没有C变量用作输出,并且没有C表达式用作输入。但是内存被列为破坏,因此编译器知道在下一条指令执行之前已经完成了挂起的读写操作。


  

......我不明白...... __volatile__

的含义

好的,所以这是一堆蠕虫,因为GCC和Visual Studio以不同的方式解释volatile的含义(即使它们使用相同的C语言规范)。

在GCC中,使用volatile的唯一原因是硬件可以改变内存。所以我认为在上面的例子中使用限定符volatile是一种滥用(因为看起来该函数正在扫描NULL字节,而不执行内存映射I / O)。

您可以在volatile shared memory找到GCC邮件列表上的相关讨论。 Ian Lance Taylor提供了以下答复,是GCC开发人员之一:

  

不,不能解决这个问题。这不是什么波动   限定词是为了。 volatile限定符专为使用而设计   内存映射硬件。它不是为多处理器共享而设计的   记忆。如果程序不是多处理器安全的,那么添加   volatile永远不会使多处理器安全。


编辑:正如Tony在下面指出的那样volatile is used to tame the optimizer,以便在编译期间不会删除ASM块。


另请注意,您可以将代码转换为x86的内联汇编程序,但是您无法为x64执行此操作。 Microsoft不支持x64的内联汇编。请参阅MSDN上的Intrinsics and Inline Assembly