【问题标题】:Assembly Language equivalent to Ceil , Floor相当于 Ceil , Floor 的汇编语言
【发布时间】:2019-11-06 20:29:06
【问题描述】:

ceil, floor 的 x86 等价物是什么? 我不能特别谷歌相应的说明。 等价物可能不一定是单指令,尽管优选单指令。

【问题讨论】:

  • 这能回答你的问题吗? Math.h library functions in assembly x86?
  • 感谢您的回复。但我正在寻找 FPU 可以处理的东西,例如它具有截断和舍入浮点数的功能。我正在寻找类似的东西。
  • 您使用哪种 FPU? x87 FPU 还是 SSE FPU?答案会有所不同,具体取决于您要使用的 FPU。
  • 我使用的是 x87 FPU

标签: assembly x86 floor ceil x87


【解决方案1】:

单指令层/天花板仅适用于 SSE4.1 roundsd / roundpd,并且仅适用于 XMM 而不是旧版 x87。


使用 x87,您可以设置当前的舍入模式,然后使用 frndint。 (http://www.ray.masmcode.com/tutorial/fpuchap1.htm 显示了 RC 位在 x87 控制字中的位置)。可用的舍入模式包括最接近偶数(默认)、朝向 +Inf(ceil)、朝向 -Inf(下限)和朝向零(trunc)。

完成后不要忘记重新设置舍入模式。

显然frndint 在某些 CPU (https://agner.org/optimize) 上速度较慢,因此使用fistp / fild 转换为整数并返回实际上可以更快(仍然适当设置舍入模式)。但这仅适用于可以表示为有符号 64 位整数的 FP 值(假设您使用 qword 内存操作数)。您可以改为添加/减去适当的幻数(以使值非常大,强制舍入)。同样,这可能需要设置舍入模式。

当然,如果您想要(int)floor(x),那么绝对只是fistp,并根据需要设置舍入模式。

使用 SSE3,您可以使用 fisttp 将其截断为 0(添加它是为了加快 C float->int 转换的速度,即使 SSE 可用,仍希望使用旧版 x87)。

floor == trunc 用于非负值,因此您可以在这种情况下利用高效的fisttp 或 SSE XMM 截断。


对于 SSE4.1,对于 XMM 寄存器中的标量 double,您可以使用 roundsd 舍入到最接近的整数值 double,并选择由立即操作数。 (不是转换,只是像frndint 这样的双->双舍入,所以它适用于任何值)。提供压缩和标量单精度和双精度版本。

使用 SSE4.1,roundsd + cvtsd2si(int)floor(x) 的最佳选择。或者如果你知道你的值是非负的,你可以使用 SSE2 cvttsd2si。注意“截断”的额外t。 (对于单精度或带有 cvtpd2dq 的打包 SIMD 也是如此。)

【讨论】:

    猜你喜欢
    • 2012-03-29
    • 2017-02-19
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    相关资源
    最近更新 更多