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位操作数的支持,他们认为没有理由使用非弹出版本。他们可能已经用完了操作码编码。)

  • 有很多关于x86指令集的在线参考。例如,是大多数谷歌搜索的热门。或者您可以查看(
    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。这个问题对我来说没有多大意义,所以我尽力回答了。我认为我的解释是正确的,所以我试图为其他人澄清这个问题。它还没有得到答复。我想那是因为其他人也不明白。很抱歉,请随意修改。