我正在尝试使用以下宏:
#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。
任何人都可以澄清一些事情吗?
此致
答案 0 :(得分:3)
“我不知道如何使用比现在更少的寄存器” - 如何使用immediates而不是寄存器来获取两个maxint / minint常量? (啊,cmov
不会立即使用。但你可以为{1}}自己存储常量,而不是要求编译器提前将它们设置在不同的寄存器中。
另外,为什么要在%edi
中构建所有内容,然后在最后将其复制到另一个寄存器?所有操作都不是%ebx
具有特殊含义的操作,因此只需将%ebx
替换为%%ebx
并将其声明为%0
而不是"&=r"
将是无论是胜利还是至少不是亏损。