C内联汇编 - 'fst'的操作数类型不匹配

时间:2012-01-05 01:43:41

标签: c gcc assembly mingw inline-assembly

嘿我试着学习如何在我的C程序中编写汇编代码。我理解大会中的整数,但花车继续绊倒我。

double asmSqrt(double x) {
    double o;
    __asm__ ("fld %1;"
             "fsqrt;"
             "fst %0;"
             : "=g" (o)
             : "g"  (x)
    );
    return o;
}

正如你所看到的,我只想找到x的平方根。但每当我尝试编译它时,我得到一个操作数类型不匹配错误。

我遵循此处使用的相同语法:http://www.codeproject.com/KB/cpp/edujini_inline_asm.aspx?display=Print

PS:我在Windows XP上使用MinGW GCC

4 个答案:

答案 0 :(得分:3)

您需要明确指定所需的fldfst指令变体。否则,编译器不知道您的操作数应该是多大。这段代码在这里适用于我:

__asm__ ("fldl %1  ;"
         "fsqrt    ;"
         "fstl %0  ;"
         : "=g" (o)
         : "g"  (x)
);

您可以使用反汇编程序仔细检查是否正在发出64位FLD和FST(DD/0DD/2)的右操作码。

答案 1 :(得分:1)

首先,你为什么要这样做?编译器本身可以做平方根。您只需调用正确的数学库函数,启用优化(因此它将内联标准函数),如果它不能满足您的需求,我会感到惊讶。结果是平台无关的(即如果你想要,你可以构建64位,甚至是整个其他架构),易于维护代码 - 更好!

如果你坚持这么做,gcc也可以在这里帮忙(我实际上没有测试过这个):

double asmSqrt(double x) {
  __asm__ ("fsqrt" : "+t" (x));
  return x;
}

t约束意味着将值放在浮点堆栈的顶部 - 您不必关心它是如何到达那里的。 +表示使用输入和输出值。

编辑:哦,如果你想自己把东西寄存在寄存器中那么你最好在'clobbers'部分告诉编译器,或者你可能会覆盖它存储在那里的东西。

答案 2 :(得分:0)

double sqrt1(double n) { __asm {           fld n           FSQRT      } }

调用方法:double result = sqrt1((double)10)例如

答案 3 :(得分:-2)

指定内存位置" = m"而不是" = g"。但最好是在这里阅读本手册:http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#s4

无论如何,这是解决方案:

double asmSqrt(double x) {
  double o;
  __asm__ ("fld %1;"
           "fsqrt;"
           "fst %0;"
           : "=m" (o)
           : "g" (x)
  );
  return o;
}