C Inline assembly - Operand type mismatch for 'fst'

倾然丶 夕夏残阳落幕 提交于 2019-12-12 17:49:47

问题


Hey Im trying to learn how to write assembly code in my C programs. I understand integers in assembly but floats continue to trip me up.

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

As you can see Im just trying to find the square root of x. But whenever I try to compile it I get an operand type mismatch error.

I followed the same syntax used here: http://www.codeproject.com/KB/cpp/edujini_inline_asm.aspx?display=Print

PS: Im using MinGW GCC on Windows XP


回答1:


You need to explicitly specify which fld and fst instruction variants you want. Otherwise, the compiler doesn't know what size your operand is supposed to be. This code works for me here:

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

You can use a disassembler to double-check that the right opcodes for 64-bit FLD and FST (DD/0 and DD/2) are getting emitted.




回答2:


First, why are you doing this? The compiler can do square roots itself. You just call the proper math library function, enable optimization (so it will inline standard functions) and I'd be surprised if it doesn't do what you want. The result is platform independent (i.e. you can build for 64-bit if you want, or even a whole other architecture), easy to maintain code - much better!

If you insist on doing it the hard way, gcc can also help here (I've not actually tested this):

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

The t constraint means put the value on the top of the floating-point stack - you don't have to care how it gets there. The + means to use the value for both input and output.

Edit: Oh, and if you do want to put things in registers yourself then you had better tell the compiler about that in the 'clobbers' section or you might overwrite something it has stored there.




回答3:


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

call the method: double result = sqrt1((double)10) for example




回答4:


Specify memory location "=m" instead of "=g". But best is to read this manual here: http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#s4

Anyway, here is the solution:

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


来源:https://stackoverflow.com/questions/8736601/c-inline-assembly-operand-type-mismatch-for-fst

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!