【问题标题】:floating point - absolute value - inline assembly - edited new code浮点 - 绝对值 - 内联汇编 - 编辑新代码
【发布时间】:2010-02-15 05:05:32
【问题描述】:

我写了一个名为 absD 的函数,我想返回它的参数的绝对值。 我正在使用带有 cygwin 的 GCC 内联汇编..

我不明白为什么它不起作用。我正在加载到内存中。然后进入 st(0) 我在哪里使用 fabs - 绝对值。我必须分配内存吗?

我正在尝试在这里学习 C 汇编,所以请多多关照。请给我很好的帮助。 谢谢

这是代码,然后是错误:

#include <stdio.h>
#include <stdlib.h>
#define PRECISION   3

double absD (double n)
{


asm(
        "fldl %[nIn]\n"
        "fabs\n"
        "fstpl %[nOut]\n"
        : [nOut] "=m" (n)
        : [nIn] "m" (n)
);



return n;


}

int main (int argc, char **argv)
{
double  n = 0.0;

printf("Absolute value\n");
if (argc > 1)
    n = atof(argv[1]);

printf("abs(%.*f) = %.*f\n", PRECISION, n, PRECISION, absD(n));

return 0;
}

这是输出:

~ $ gc a3
gcc -Wall -g a3.c -o a3
~ $ ./a3
Absolute value
abs(0.000) = 0.000
~ $

不输出其绝对值... 谢谢。。

【问题讨论】:

  • 为什么不只包括math.h 并使用fabs( )?这通常至少与您在这里所拥有的一样快。如果您还想更快,请使用 GCC 特定的内在函数 __builtin_fabs( )
  • 零的绝对值为零。有什么问题?

标签: c assembly


【解决方案1】:

它完全有效..!!您只是忘记将值放入 argv。你可以这样运行程序:

./a3 -1.3

它应该返回 1.3

在此处发布之前您已经完成...

【讨论】:

    【解决方案2】:

    fld (%eax) 表示“从地址%eax 处的值加载浮点数”。显然,%eax 的内容是双精度数,而不是指向浮点数的指针,这就是您出现段错误的原因。

    由于输入已经在堆栈中(因此它有一个地址),所以没有必要跳过箍来移动东西。

    double absD(double input) {
        double output;
        asm(
                "fldl %[input]\n"
                "fabs\n"
                "fstpl %[output]\n"
                : [output] "=m" (output)
                : [input] "m" (input)
        );
        return output;
    }
    

    另外,您的printf 格式错误:%f 表示float,但您给它的是double;你想使用%g

    【讨论】:

    • 您对 printf 的看法是错误的 - 因为它是一个可变参数函数,所以不可能将 float 传递给它(当变量参数的一部分时,它们总是被提升为 double列表)。 %f 需要 double
    • 为什么要使用内存操作数? asm("fabs" : "=t"(input) : "t"(output)); 应该可以工作,并让编译器为您执行加载(并将结果留在 FP 寄存器中,返回值所在的位置,或者内联时可以立即使用的位置。这仍然比避免效率低完全内联 asm,因为它打败了不断的传播和类似的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-30
    • 2012-06-16
    • 2015-03-17
    相关资源
    最近更新 更多