我正在学习GCC扩展的asm选项
asm goto (
"clc\n"
"lo:\t"
"lods\t%[ax]\n\t"
"lea\t%[wc](%[base], %[off], %[k]), %[la]"
"adc\t%[ax], (%[la])\n\t"
"inc\t%[off]\n\t"
"jnz\tlo\n\t"
"jnc\t%l[nocarry]\n"
:
: [base] "d" (th), [oz] "S" (oz), [wc] "I" (wc*sizeof(uInt)),
[k] "N" (sizeof(uInt)), [la] "b" (0), [ax] "a" (0), [off] "c" (-wc)
:
: nocarry
);
进行编译:
> impossible constraint in 'asm'
尝试逐个评论所有约束,同样的结果。 请帮助!
gcc版本4.6.1(Ubuntu / Linaro 4.6.1-9ubuntu3),i686-linux-gnu(32位), kernel 3.0.0-14-generic
答案 0 :(得分:3)
您的陈述是部分的,并且缺少用于填充汇编指令的输入约束的变量的定义。
最可能的候选者是[wc] "I" (wc * sizeof(uInt))
表达式,如果wc
是除了编译时常量之外的任何其他内容 - "I"
约束必须可以立即求值。也可以是[k] "N" (sizeof(uInt))
,因为它与lea
不匹配。
我建议将声明更改为:
asm (
"lea (%[base], %[off], %[k]), %[base]\n\t"
"neg %[off]\n\t"
"clc\n\t"
"lo: "
"lods %[ax]\n\t"
"lea (%[base], %[off], %[k]), %[la]\n\t"
"adc %[ax], (%[la])\n\t"
"inc %[off]\n\t"
"jnz lo\n\t"
"jnc %l[nocarry]\n"
:
: [k] "I"(sizeof(uInt)), [base] "d" (th), [oz] "S" (oz),
[la] "b" (0), [ax] "a" (0), [off] "c" (wc)
:
: nocarry
);
但您可能想要评估让编译器更自由地选择(比如说[base] "r" (th + wc)
假设th
是uInt*
)。同样,根据您的汇编指令,没有明确需要使用"a"
,"b"
,"c"
或"d"
,因此您人为地限制编译器可能选择的reg。如果这就是你想要的,那么在组装中完全编写函数比尝试强制编译器更好/更容易。
答案 1 :(得分:0)
BigInt & BigInt::operator+=(const BigInt &rhs)
{
this->grow(rhs.wc);
uInt *th = (uInt*)words, *oz = (uInt*)rhs.words;
asm goto (
"clc\n"
"l1:\t"
"mov\t(%[oz]), %[ax]\n\t"
"adc\t%[ax], (%[th])\n\t"
"lahf\n\t"
"add\t%[ws], %[th]\n\t"
"add\t%[ws], %[oz]\n\t"
"sahf\n\t"
"loop\tl1\n\t"
"jnc\t%l[nocarry]\n"
:
: [th] "r" (th), [oz] "r" (oz),
[ws] "I" (sizeof(uInt)), [ax] "a" ((uInt)0), "c" (wc)
:
: nocarry
);