我经常使用/QIfist
compiler switch,这会导致编译器生成FISTP
指令以将浮点值舍入为整数,而不是调用_ftol
辅助函数。
如何使用FIST(P) DWORD
代替QWORD
?
FIST QWORD
要求CPU将结果存储在堆栈中,然后将堆栈读入寄存器并最终存储到目标存储器,而FIST DWORD
只是直接存储到目标存储器中。
答案 0 :(得分:0)
FIST QWORD要求CPU将结果存储在堆栈中,然后将堆栈读入寄存器并最终存储到目标存储器,而FIST DWORD只是直接存储到目标存储器中。
我不明白你在这里想说什么
FIST
和FISTP
指令在两个方面有所不同:
FISTP
弹出浮点数堆栈的最高值,而FIST
则没有。这是明显的区别,并反映在操作码命名中:FISTP
具有P
后缀,这意味着“pop”,就像ADDP
等等。
FISTP
有一个额外的编码适用于64位(QWORD
)个操作数。这意味着您可以使用FISTP
将浮点值转换为64位整数。另一方面,FIST
最大值为32位(DWORD
)个操作数。
(我认为没有技术上的原因。我当然无法想象它与弹出行为有关。我假设当英特尔工程师在一段时间后添加对64位操作数的支持时,他们认为没有理由不使用非弹出版本。他们可能已用完了操作码编码。)
x86指令集有很多在线参考资料。例如,this site是大多数Google搜索的热门搜索。或者您可以查看Intel's manuals(FIST
/ FISTP
位于第365页)。
两条指令读取的值,以及它们存储的值是完全相同的。两者都从浮点堆栈顶部读取值,并将结果存储到内存中。
使用FIST
代替FISTP
的编译器绝对没有优势。请记住,当从函数退出时,始终必须从浮点堆栈中弹出所有值,因此如果使用FIST
,则必须再追加FSTP
FISTP
1}}指令。这可能不会慢,但它会不必要地膨胀代码。
此外,还有另一个原因,编译器更喜欢FIST
:支持64位操作数。它允许代码生成器完全相同,无论您要舍入到什么大小的整数。
时间您可能更喜欢使用FIST
,如果您是手写汇编代码并希望在堆栈之后重复使用浮点值四舍五入。编译器不需要这样做。
所以,无论如何,所有这些都说明你的问题的答案是否定的。无法使编译器自动生成int32 RoundToNearestEven(float value)
{
int32 result;
__asm
{
fld DWORD PTR value
fist DWORD PTR result
// do something with the value on the floating point stack...
//
// ... but be sure to pop it off before returning
fstp st(0)
}
return result;
}
指令。如果你仍然坚持,你可以编写使用你想要的任何指令的内联汇编:
{{1}}