首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FPTAN实例x86

FPTAN实例x86
EN

Stack Overflow用户
提问于 2017-06-15 18:59:10
回答 1查看 1.3K关注 0票数 1

根据英特尔的文档,这就是FPTAN所做的:

用其近似切线替换ST(0),并将1推到FPU堆栈上。

这是我在NASM上写的代码:

代码语言:javascript
复制
section .data
    fVal: dd 4
    fSt0: dq 0.0
    fSt1: dq 0.0

section .text
    fldpi
    fdiv  dword[fVal]  ; divide pi by 4 and store result in ST(0).
    fptan
    fstp  qword[fSt0]  ; store ST(0)
    fstp  qword[fSt1]  ; store ST(1)

在这里,我发现fSt0fSt1的值是:

fSt0 = 5.60479e+044

fSt1 = -1.#IND

但是,fSt0fSt1不应该都是1

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-16 00:42:27

正如Michael已经在评论中指出的那样,您有一个简单的错误。您没有将fVal声明为浮点值(如预期的那样),而是将其声明为32位整数。更改:

代码语言:javascript
复制
fVal: dd 4

至:

代码语言:javascript
复制
fVal: dd 4.0

然后,您的代码将按预期工作。它写得很正确。

如果要接受整数输入,可以通过更改代码以使用FIDIV指令来实现。该指令将首先将一个整数转换为一个双精度浮点值,然后执行以下除法:

代码语言:javascript
复制
fldpi
fidiv  dword [fVal]    ; st(0) = pi / fVal
fptan                  ; st(0) = tan(st(0))
                       ; st(1) = 1.0
fstp   qword [fSt0]
fstp   qword [fSt1]

但是由于转换是必需的,所以这比刚刚将输入作为浮点值提供的效率略低。

请注意,如果要这样做,在某些旧CPU上分解负载将更有效,以便将其与除法分离-例如,

代码语言:javascript
复制
fldpi
fild   dword [fVal]
fdivp  st(1), st(0)    ; st(0) = pi / fVal
fptan                  ; st(0) = tan(st(0))
                       ; st(1) = 1.0
fstp   qword [fSt0]
fstp   qword [fSt1]

换句话说,我们将FIDIV指令分解成单独的FILD (整数加载)和FDIVP (除法和pop)指令。这改善了重叠,从而减少了代码执行速度的几个时钟周期。(在较新的CPU上,来自AMD家族15h推土机和英特尔奔腾II及更高版本--将FIDIV分解为FILD+FDIV没有真正的优势;无论用哪种方式编写它,都应该具有同等的性能。)

当然,由于这里的所有内容都是常量,并且是tan(pi/4) == 1,所以您的代码相当于:

代码语言:javascript
复制
fld1
fld1

…这就是优化编译器会产生的结果。:-)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44574993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档