内联汇编器直接双倍到长长转换

inline assembler direct double to long long conversion

本文关键字:转换 汇编器      更新时间:2023-10-16

由于优化原因,我想直接调用(使用内联汇编程序)到函数"FLDL"和"拳头"。可悲的是,我不知道如何运行它,因为我不是汇编程序中的那个神。

我没有比这更进一步:

double* input;         
long long output;
__asm fldl input;      
__asm fist output;

__asm fld input实际上会尝试读取指针值,就好像它是浮点值一样。如果要读取指针指向的浮点值,则必须经历两个步骤:将地址读入寄存器,然后使用寄存器中的地址读取数据。在 32 位平台上,它将是类似于

__asm {
  mov eax, input
  fld qword ptr [eax]
  fistp output
}

我刚刚在VS2005中尝试过,它可以工作。(请注意,正如其他人在评论中所说,fist不支持存储到 64 位long long ,而fistp支持。但无论如何,你可能都需要fistp,即一个弹出式商店。

最简单的可能是:

double input;
long long output;
__asm fld input
__asm fisttp output

这将执行"正常"的双倍到长整型转换,截断为零,就像 C 转换一样。 非常旧的(奔腾4之前)CPU不支持fistpp,但是,因此在此类机器上,您需要改用fistp,它使用当前的舍入模式(通常舍入到最接近)。 因此,如果您想例如向 -无穷大四舍五入,则需要保存当前的舍入模式,将其设置为您想要的,执行fistp并恢复舍入模式:

double input;
long long output;
unsigned short oldcw, cw;
__asm fld input
__asm fstcw oldcw
cw = (oldcw & ~0xc00) | 0x400; // round towards -infinity
__asm fldcw cw
__asm fistp output
__asm fldcw oldcw