宏asm内联错误

时间:2011-08-26 17:14:16

标签: gcc assembly

我正在尝试使用以下宏:

#define M_MA(out, L_v, var1, var2)({ \
    asm volatile(  \
    "movswl %2, %%edi\n\t" \
    "movswl %3, %%ebx\n\t" \
    "imull %%edi, %%ebx\n\t" \
    "sall $1,%%ebx\n\t" \
    "cmpl %4,%%ebx\n\t" \
    "cmove %5,%%ebx\n\t" \
    "addl %1, %%ebx\n\t" \
    "jno out%=\n\t" \
    "cmovg %5, %%ebx\n\t" \
    "cmovl %4, %%ebx\n\t" \
    "out%=: nop\n\t" \
    "movl %%ebx, %0\n\t" : "=r"(out) : "r"(L_v), "m"(var1), "m"(var2), "r"(-2147483648), "r"(+2147483647) : "%ebx","%edi");  })

当在使用优化编译的文件中使用它时,我得到:

error: ‘asm’ operand has impossible constraints

var1 var2 是16位字。 out L_v 是32位字。

经过一些阅读后,我认为问题在于编译器需要的寄存器多于可用的寄存器,但我不确定。如果这是问题,我不知道如何使用比现在更少的寄存器或如何修复错误。

我在32位平台上使用gcc而不是Linux。

任何人都可以澄清一些事情吗?

此致

1 个答案:

答案 0 :(得分:3)

“我不知道如何使用比现在更少的寄存器” - 如何使用immediates而不是寄存器来获取两个maxint / minint常量? (啊,cmov不会立即使用。但你可以为{1}}自己存储常量,而不是要求编译器提前将它们设置在不同的寄存器中。

另外,为什么要在%edi中构建所有内容,然后在最后将其复制到另一个寄存器?所有操作都不是%ebx具有特殊含义的操作,因此只需将%ebx替换为%%ebx并将其声明为%0而不是"&=r"将是无论是胜利还是至少不是亏损。