内联汇编程序直接双向长转换

时间:2012-11-30 16:48:39

标签: c++ visual-studio-2005 x86 inline-assembly

由于优化原因,我考虑直接调用(使用内联汇编程序) 功能“fldl”和“拳头”。可悲的是,我不知道如何运行它,因为我不是汇编程序中的上帝。

我没有比这更进一步:

double* input;         
long long output;

__asm fldl input;      
__asm fist output;

2 个答案:

答案 0 :(得分:1)

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

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

我刚刚在VS2005中试过它并且它可以工作。 (请注意,正如其他人在评论中所述,fist不支持存储到64位long long,而fistp则支持存储。但是你可能还需要fistp,即一个弹出的商店。)

答案 1 :(得分:0)

最简单的可能是:

double input;
long long output;

__asm fld input
__asm fisttp output

这是一个'正常'的双向长转换,截断为零,就像C强制转换一样。很老(Pentium4之前的)CPU不支持fistpp,所以在这样的机器上你需要使用fistp代替它,它使用当前的舍入模式(通常是舍入到最近的)。因此,如果你想要例如舍入-infinity,你需要保存当前的舍入模式,将其设置为你想要的,执行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