Visual c++ 使用/QIfist选项强制MSVC生成FIST指令
我经常使用,这会导致编译器生成Visual c++ 使用/QIfist选项强制MSVC生成FIST指令,visual-c++,x86,intel,fpu,Visual C++,X86,Intel,Fpu,我经常使用,这会导致编译器生成FISTP指令,将浮点值舍入为整数,而不是调用\u ftol辅助函数 如何使其使用first(p)DWORD,而不是QWORD FIST QWORD要求CPU将结果存储在堆栈上,然后将堆栈读入寄存器,最后存储到目标内存,而FIST DWORD只直接存储到目标内存中 First QWORD要求CPU将结果存储在堆栈上,然后将堆栈读入寄存器,最后存储到目标内存中,而First DWORD只直接存储到目标内存中 我不明白你想说什么。 FIST和FISTP指令在两个方面完全
FISTP
指令,将浮点值舍入为整数,而不是调用\u ftol
辅助函数
如何使其使用first(p)DWORD
,而不是QWORD
FIST QWORD
要求CPU将结果存储在堆栈上,然后将堆栈读入寄存器,最后存储到目标内存,而FIST DWORD
只直接存储到目标内存中
First QWORD要求CPU将结果存储在堆栈上,然后将堆栈读入寄存器,最后存储到目标内存中,而First DWORD只直接存储到目标内存中
我不明白你想说什么。FIST
和FISTP
指令在两个方面完全不同:
FISTP
弹出浮点堆栈的顶部值,而FIST
不弹出。这是明显的区别,并反映在操作码命名中:FISTP
有P
后缀,意思是“pop”,就像ADDP
一样FISTP
有一个额外的编码用于64位(QWORD
)操作数。这意味着您可以使用FISTP
将浮点值转换为64位整数<另一方面,code>FIST在32位(DWORD
)操作数处最大
(我不认为这有什么技术原因。我当然无法想象这与弹出行为有关。我假设英特尔工程师在一段时间后增加了对64位操作数的支持,他们认为没有理由使用非弹出版本。他们可能已经用完了操作码编码。)FIST
/FISTP
在第365页)
这两条指令从何处读取值以及将值存储到何处完全相同。两者都从浮点堆栈顶部读取值,并将结果存储到内存中。
使用FIST
而不是FISTP
对编译器绝对没有好处。请记住,在退出函数时,始终必须弹出浮点堆栈中的所有值,因此如果使用first
,则必须在它之后再执行一条FSTP
指令。这可能不会再慢了,但它会毫无必要地夸大代码
此外,编译器更喜欢FISTP的另一个原因是:支持64位操作数。它允许代码生成器是相同的,而不管您要舍入到什么大小的整数
您可能更喜欢使用first
的唯一时间是,如果您正在手工编写汇编代码,并且希望在对堆栈进行四舍五入后重新使用堆栈上的浮点值。编译器不需要这样做
总之,所有这些都表明你的问题的答案是否定的。编译器不能自动生成first
指令。如果您仍然坚持,您可以编写使用任何指令的内联程序集:
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;
}
阿格纳·福格的文件第14.8章很好地介绍了这些选项,因此,似乎不可能使用DWORD。你已经更改了我问题的标题,完全改变了含义。我根本不在乎编译器是否会使用
FIST
或FISTP
,我只想让它使用DWORD
而不是QWORD
。编译器使用64位并生成以下代码:FISTP QWORD PTR[esp+xx]:MOV EAX[esp+xx]:MOV[DEST],EAX
,它可以使用32位并生成单个FISTP[DEST]
。因为我知道这个数字适合32位,所以我认为编译器没有理由使用64位version.Hmm。这个问题对我来说没有多大意义,所以我尽力回答了。我认为我的解释是正确的,所以我试图为其他人澄清这个问题。它还没有得到答复。我想那是因为其他人也不明白。很抱歉,请随意修改。