在 x86_64 汇编问题中添加双精度

Posted

技术标签:

【中文标题】在 x86_64 汇编问题中添加双精度【英文标题】:Adding doubles in x86_64 assembly problems 【发布时间】:2013-10-23 00:41:02 【问题描述】:

您好,我正在尝试学习汇编并学习如何在 x86_64 中使用浮点数。据我了解,参数在 xmm0、xmm1、xmm2 等中传递,结果在 xmm0 中返回。所以我正在尝试制作一个简单的汇编函数,将加倍加在一起。这是函数

.text

.global floatadd
.type floatadd,@function

floatadd:
    addsd %xmm1,%xmm0
    ret

这也是我正在使用的 C 代码。

#include<stdio.h>

int main()
    double a = 1.5;
    double b = 1.2;
    double c = floatadd(a,b);
    printf("result = %f\n",c);

我一直在尝试关注 gdb 中发生的事情。当我在函数中设置断点时,我可以看到 xmm0 有 1.5,xmm1 有 1.2,当它们加在一起时,它们是 2.7。在 gdb print $xmm0 中给出 v2_double = 2.7000000000000002, 0 但是当我的函数从 main 返回并调用时

cvtsi2sd %eax,%xmm0 

打印 $xmm0 变为 v2_double = 2, 0。我不知道为什么 gcc 调用它或为什么它使用 32 位寄存器而不是 64 位寄存器。我尝试过使用修饰符 %lf 和 %f,它们都做同样的事情。

发生了什么?

【问题讨论】:

floatadd 的原型在哪里?如果您没有指定一个,您的编译器会将 floatadd 视为返回 int,这将解释该指令的使用。 【参考方案1】:

问题是您在调用floatadd 之前未能声明它。所以编译器假定它在%eax 中返回一个int 并将该int 转换为double。添加声明:

double floatadd(double, double);

在main之前。

使用-Wall 或您的编译器用来启用警告的任何等效项可能会告诉您这个问题...

【讨论】:

好吧,我想我是个白痴。好吧,至少我知道我对汇编的理解没有错。谢谢! @user2825351:如果它解决了你的问题,请确保你接受这个答案。

以上是关于在 x86_64 汇编问题中添加双精度的主要内容,如果未能解决你的问题,请参考以下文章

x86_64 汇编 Linux 系统调用混淆

如何在 GCC (x86_64) 中使用内联汇编进行相对跳转/调用

使用 GNU 汇编器在 x86_64 中调用 printf

从 i386 移动到 x86_64 时的浮点精度

x86-64 在线汇编,带有诸如 https://www.mycompiler.io/new/asm-x86_64 之类的 IDE

x86_64 汇编器的 gcc 错误(操作码 0x83 cmp m64/imm8)