【问题标题】:x86 Assembly fcos/fsin wrong resultx86 汇编 fcos/fsin 错误结果
【发布时间】:2018-09-30 15:09:09
【问题描述】:

我想在汇编中做什么:

facing_x = math.cos(Pitch) * math.cos(Yaw)

我是怎么做的:

fld qword [Pitch] 
fcos 
fst [cos]
fld qword [Yaw]
fcos 
fst [cos2]
movss xmm5,[cos] 
movss xmm7,[cos2] 
mulss xmm5,xmm7 
movss [facing_x],xmm5

我总是得到:1

无论两个输入,我总是得到 1 或 0 作为结果 face_x

我做错了什么?我的意思是肯定有什么我不明白的地方!

【问题讨论】:

  • 您是否尝试过用 c 编写代码并查看程序集是什么?
  • 哦,fst 可能默认为 64b 或 80b 精确,你甚至没有写你使用的编译器......但movss 正在寻找“浮动”,所以@ 987654325@ 可能会更安全。再次使用调试器检查是验证存储/恢复正确字节数以及所有转换/值是否符合预期的最简单方法。
  • 您不妨使用fmul。除非您需要将您的 cos 结果舍入为单精度,否则将它们存储到内存并使用 SSE1 重新加载是零点。比如 fld / fcos / fld / fcos / fmulp / fstp dword [facing_x]。注意使用fmulpfstp来弹出两个cos结果。
  • 请出示您的完整代码,包括PitchYaw等的定义。您显示的 sn-p 不足以正确诊断您的问题。
  • AFAIK,@PeterCordes 观察到的行为甚至记录在原始 8087 数据表中。

标签: assembly x86 x87


【解决方案1】:

老帖子,但我想把答案。

改进的代码:

finit
fld dword [Pitch]
mov dword [Math],0x42652EE1 //57.29577951308232
fld dword [Math]
fdivp st(1),st(0)
fcos
fld dword [Yaw]
fld dword [Math]
fdivp st(1),st(0)
fcos
fmulp st(1),st(0)
fstp dword [result]

旧代码:

finit
fld dword [Pitch]
mov dword [Math],0x42652EE1 //57.29577951308232
fld dword [Math]
fdivp st(1),st(0)
fcos
fld dword [Yaw]
mov dword [Math],0x42652EE1 //57.29577951308232
fld dword [Math]
fdivp st(1),st(0)
fcos
fmulp st(1),st(0)
fld dword [facingX]
fxch
fcomip st(1)
fstp dword [Math]
jne l611786
fld1
jmp l412411

l611786:
fldz

l412411:
fstp dword [result]

【讨论】:

  • 代码审查:1.0 和 0.0 可以用整数 mov 存储(1.0 的正确位模式)。你不需要 fld1 / fldz / fstp,只需要像你用 mov dword [Math],0x42652EE1 做的整数东西。 (你做了两次,多余的)。 IDK 为什么要存储到命名的静态存储临时而不是使用调用堆栈(例如push 0x42652EE1 / fld dword [esp]),或者像编译器使用的那样已经具有正确值的只读常量。此外,如果您只想使用jne,则不需要fxch
  • 感谢您的回复,我已经编辑了我的评论。你能检查我是否做得正确吗?我习惯使用 [Math] 很多,但我看到了不便
  • 您的新代码不会对 fcomip st(1) 的 FLAGS 结果做任何事情。但是 IDK 您的第一个答案版本中的任何内容都与 facing_x = math.cos(Pitch) * math.cos(Yaw) 的原始问题有关。这不需要任何除法或比较,并在[-1.0, +1.0] 之间产生任何实际输出,而不仅仅是 0.0 或 1.0。所以,是的,你的新版本更接近了。
  • 您的回答归结为“我没有意识到 fcos 使用弧度”,即使它被记录为:“The source operand must be given in radians”——而且您从未回答询问输入的评论PitchYaw ...
  • 原始代码来自一个旧项目,我认为的公式不是正确的公式。如果你愿意,我会删除我的答案。 (数据来自加速度计)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-23
相关资源
最近更新 更多