tags:

views:

425

answers:

3

I wrote a function named absD that i want to return the absolute value of its argument.. I am using GCC inline assembly with cygwin..

I dont see why its not working. i m loading into memory. then into st(0) where i am using fabs - absolute value. Do i have to allocate memory?

I am trying to learn assembly with C here so please be nice. Please give me good help. Thank you

heres the code and then the error:

#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;
}

here is the output:

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

Not outputing its absolute value... Thank you..

A: 

Sorry not an expert in that field, does eax is big enough to store a double on your platform (win32 x86 I assume) ? (not sure why this was not flagged with a warning).

Good luck

call me Steve
+2  A: 

fld (%eax) means "load a float from the value at address %eax". Obviously, the contents of %eax are a double, and not a pointer to a float, which is why you segfault.

Since the input is already on the stack (thus it has an address), there's no need to jump through hoops moving things around.

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

Also, your printf format is wrong: %f means float, but you're giving it a double; you want to use %g.

ephemient
You're wrong about `printf` - because it's a varargs function, it's impossible to pass it a `float` (they're always promoted to `double` when part of the variable-argument-list). `%f` expects a `double`.
caf
ephemient - this doesnt work.. its ouputing 0.0 - just not its absolute value...
icelated