Working with double-precision numbers in inline assembly (GCC, IA-32)

浪尽此生 提交于 2019-11-30 14:42:10

At least one issue with your current code is it is using the single precision floating point versions of fld and fstp. If you replace them with fldl and fstpl it will probably work.

Here's what I've got. It's not tested, but hopefully would be less gnarly for you to work with. :-)

double
roundd(double n, short mode)
{
    short cw, newcw;

    __asm__("fstcw %w0" : "=m" (cw));
    newcw = cw & 0xf3ff | mode;
    __asm__("fldcw %w0" : : "m" (newcw));
    __asm__("frndint" : "+t" (n));
    __asm__("fldcw %w0" : : "m" (cw));
    return n;
}

Although, if you're not required to use assembly to achieve your rounding mode, think about using the functions in <fenv.h> instead. :-)

As the sign changes, it means that the sign bit (which is the most significant, the first one) is not correct. That suppose to me that the pointer %1 is wrongly aligned. If you have one byte, it can begin on 0,1,2... but if you access two bytes, the address must be 0,2,4.... and in case of double the address must be even dividable by 8: 0,8,16

So check if the address which you use to load the value is dividable by 8. Assembly has the align keyword to guarantee that your data is correctly aligned.

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