【问题标题】:x87 FPU and integer arithmetic?x87 FPU和整数运算?
【发布时间】:2021-08-30 09:56:41
【问题描述】:

我试图了解如何使用 FPU 进行 64 位整数运算。我写这个(ATT语法):

fildq   A
fildq   B
faddp
fistpq  C

C 中的结果是 A + B + 1。如果我从“finit”指令开始,它会给我正确的值 A + B。我认为不需要的 +1 可能是因为它添加了进位位,但是使用 gdb 时,当我使用 finit 时,我在 FPU 控制寄存器中看不到任何区别——在这两种情况下,控制寄存器都以 0x27F 开始,标记寄存器为 0xFFFF(= 堆栈空),而所有其他(包括所有条件位所在的状态寄存器)都为零。

在这里使用 finit 似乎有点生硬,而且我还想知道如果我不使用它,额外的 +1 来自哪里,因为所有 FPU 寄存器似乎都具有相同的值案例。谁能帮我解释一下?

【问题讨论】:

    标签: x87


    【解决方案1】:

    [...] 当我使用 finit 时,我发现 FPU 控制寄存器与不使用时完全没有区别——在这两种情况下,控制寄存器都以 0x27F [...]

    你确定吗? finit 应该加载0x37F,与0x27F 相比设置了一个附加 位。 区别在于精度控制领域。 默认值使用 80 位,而您的观察值使用 64 位。

    C 中的结果是 A + B + 1。[…] 在这里使用 finit 似乎有点生硬,我也想知道如果我不使用它,额外的 +1 来自哪里,[...]

    如果AB 足够,您可能会看到fadd 的精度损失。 取消屏蔽精度异常将确认这一点。 我认为您正在使用您最喜欢的编译器的内联汇编功能。 如果您不想打扰琐碎的任务,这当然很方便,但显然您的编译器的运行时系统会在启动时加载 0x27F 以考虑兼容性。 详细阅读其手册(可能还有源代码)。

    【讨论】:

    • 不,我是直接用汇编程序编写的(汇编一个 .s 文件)。但是你对 finit 是对的——0x37F 有,0x27F 没有——我的错误。我正在使用以下命令进行组装:“gcc -g -o x.exe -nostartfiles -Wl,-estart -w x,s”,然后使用 gdb 逐步查看内存中的 A、B 和 C。请注意,我没有使用任何外部运行时包。我不知道是什么导致了控制寄存器的混乱。
    • @user1636349 x.exe,嗯?在 Win64 目标上,不推荐使用 x87(以及 MMX 和 3DNow!)指令集扩展。我的意思是,你的程序确实运行,但如果你的操作系统惹恼了你,我不会感到惊讶。在 Linux 和 FreeBSD 系统上我没有遇到任何困难。
    • Win32 目标,或者我可以使用整数算术指令执行 64 位整数算术。我决定尝试使用 FPU 作为 add/adc 序列的替代方案,但看起来 add/adc 更容易。
    • 为什么你认为整数运算在 x87 和 FPU 上会更好?使用 ALU 进行通用整数运算。利用 FPU 克服幅度限制可能损害精度。使用任意精度算术库来克服 GPR 的幅度限制保持精度,但速度不快。每种方法都有其优点和缺点;选择适合您的应用程序的那个。 [PS:考虑到OOE,如果你也使用ALU,理论上你也可以使用FPU来分配工作负载。]
    • 您在我的帖子顶部错过了这一点:“我正在尝试理解使用 FPU 进行 64 位整数运算。”像这样的布道根本无法帮助我理解 FPU 的整数运算能力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    • 2014-03-08
    相关资源
    最近更新 更多