【发布时间】:2019-03-09 11:24:39
【问题描述】:
我正在尝试为 C 程序构建一个 NASM 库。我想对作为参数给出的浮点数进行四舍五入。
C 函数原型如下所示:
double nearbyint(double x);
我尝试使用frndint 指令,但我需要先将参数压入堆栈。
这是我想出的(不编译):
bits 64
section .text
global nearbyint
nearbyint:
push rbp
mov rbp, rsp
fld xmm0
frndint
fstp xmm0
leave
ret
【问题讨论】:
-
你不能直接从xmm转移到fpu。您需要先将其推送到 cpu 堆栈,然后再加载到 fpu 堆栈中。请注意,您不需要 fpu,如果您有 SSE4.1,则可以使用
ROUNDSD。 -
round是此函数的错误名称。 ISO Cround()使用一种特殊的舍入模式,该模式与 IEEE754 默认最接近(甚至作为决胜局)不同。 您尝试实现的函数在 ISO C/C++ 中称为nearbyint或rint。 round() for float in C++ -
要解决没有 SSE4.1 的
roundsd的不足,您可以添加然后减去一个大数字。 (glibc 的非 SSE4.1rint在检查 + 或 - 之后执行此操作。然后有条件地对浮点位进行修复:code.woboq.org/userspace/glibc/sysdeps/ieee754/dbl-64/…)nearbyint执行相同的操作,除了必须保存/恢复 FP 异常状态以避免引发不精确异常。 -
@PeterCordes 我需要自己实现数学函数而不使用系统函数。不过,我仍然可以按照您的建议重命名。
-
是的,我就是这个意思。如果您正在(重新)实现标准库函数,请将它们命名为与标准定义一致。或者换一种说法,如果您的实现与标准行为匹配,则仅使用标准库函数的名称。
标签: assembly floating-point x86-64 nasm