将内联汇编代码段合并在一起

时间:2015-02-18 14:34:41

标签: c assembly x86 mingw inline-assembly

所以,我有这个代码按预期工作:

#include <stdio.h>

int main () {
    unsigned int i;
    int x=5;

    __asm__ ("movl %1, %0;"
             "subl %2, %0;"
           : "=r" (i)
           : "r" (4), "r" (x)
           : "0");

     __asm__ ("movl %1, %0;"
           : "=r" (x)
           : "r" (i)
           : "0");

    printf("%d\n", x);
    return 0;
}

如何将两个调用合并为一个?

2 个答案:

答案 0 :(得分:1)

这些是无意义的asm块开头。经验法则是,如果你使用mov,你可能做错了。此外,即使您声称它按预期工作,代码也会被破坏。没有什么能阻止编译器将%2分配给与产生错误代码的%0相同的寄存器。你很幸运,它并没有发生在你身上。

无论如何,第二个asm块只是将i复制到x。因此合并的asm看起来像:

__asm__ ("movl %2, %0;"
         "subl %3, %0;"
         "movl %0, %1;"
           : "=&r" (i), "=r" (x)
           : "r" (4), "r" (x));

这当然仍然很愚蠢,但至少在技术上并不是错误的。注意第一个输出的早期clobber &修饰符。但是,第二种情况并非如此。

答案 1 :(得分:1)

第一个__asm__集:i <- 4 - x。第二组:x <- i。它们可以合并为:

__asm__ ("subl %k2, %k0" : "=r" (x) : "0" ((unsigned)(4)), "g" (x));

不需要clobbers(除非你想包括"cc",这总是由gcc承担),并且在读取之前没有输入被覆盖的问题。 "g"约束表示寄存器,内存或立即操作数是可接受的。在这种情况下,输出应为:"-1"x <- 4 - 5

注意:第一个__asm__的输出应为=&r。此外,两者都不应将%0列为破坏 - 这是隐含的,因为%0在两种情况下都是输出。