如何在x86-64汇编中使用浮点数?

4

我正在处理一些x86-64汇编语言,浮点数让我感到困惑。例如,当我运行以下代码:

section .data
     omega:  dq 2.0
     omega2: dq 3.0

section .text
global func

func: push rbp
      mov rgp, rsp

      FINIT

      FLD qword [omega]
      FLD qword [omega2]
      FADD st0, st0

      mov rsp, rbp
      pop rbp
      ret

这个函数在C代码中被调用,例如:printf("%Lf \n", func() ); 不幸的是,结果是一些奇怪的数字... 我试着使用FIADD添加两个整数,它也正常工作。我已经查阅了大量资料,但也许这里有人可以指点一下我一个不错的FPU教程,或者分享她/他的经验和智慧:)
要点总结:
  • 语言:x86-64汇编
  • 汇编器:从存储库安装的nasm v.2.09.04
  • 编译器(用于C语言):gcc v.4.5.2 (与Ubuntu一起安装)
  • 操作系统:Oracle VM上的Ubuntu 11.04 64位
  • 主机操作系统:Windows 7 SP1 64位
  • 处理器:Intel i5 - 2430M 64位(检查了两次:D)
  • 问题:FPU无法添加两个数字:(
以防万一:最后,我希望能够使用FSINCOS和其他花式FPU指令,但是即使简单的加法都失败了...
先感谢大家!

2
找出复杂性的一种方法是编译一些简单的C代码,并使用反汇编器查看生成的机器代码。 - Oliver Charlesworth
好的,看起来它使用了SSE指令集。也许我明天会尝试这种方法。 - Losiowaty
4
在x86_64中,你不应该使用旧版FPU。最好使用标量SSE指令。请注意,这里的意思是建议使用SSE指令而非FPU指令来进行浮点运算。 - Gunther Piez
为什么不使用SSE/SSE2呢?它更快,而且您不会遇到堆栈问题。 - phuclv
2个回答

4

好的,最终结果表明我的问题与FPU寄存器以堆栈形式组织有关,我没有足够地注意它,导致出现了垃圾和不必要的残留物。从“标准”切换到“pop”指令版本有所帮助!

无论如何,感谢所有阅读过的人,非常感谢! :)

如果有人感兴趣-我正在做一个课堂作业,需要在汇编语言中计算一个行星相对于另一个的运动(地心模型)。这里可以查看转换为处理的最终结果。


0

在 printf %f 中使用 L 限定符会将该参数转换为 long double(80 位浮点数),这不是汇编数据类型。移除 L,它将默认为 double(64 位浮点数),这才是你要计算的。

另外,应该是

  FADD st1, st0

将两个数字相加。否则它会使第二个值加倍。


问题仍然存在。 - Losiowaty
@Losiowaty:C代码中是否有func()的声明? - wallyk
否则,在编译期间我会得到链接器错误。你关于加法公式是正确的,但无论我尝试添加/减去/除以/乘以什么都没有关系。 - Losiowaty
@Losiowaty:什么是声明?特别是返回类型。 - wallyk
我尝试了所有的类型:float、double、long double,但是代码看起来像这样:extern double func(); - Losiowaty
@Losiowaty: double func(void); 是最正确的。这是哪个C编译器?你可能需要查找一个编译器选项来返回FPU中的浮点值。 - wallyk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接