Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Working with assembly (GCC, IA-32) Can you guys please help me solve the problem

ID: 3669937 • Letter: W

Question

Working with assembly (GCC, IA-32)

Can you guys please help me solve the problem I have in the "double roundD(double n, RoundingMode roundingMode)" function it gives me an error when try to compile with GCC :

The function :

( its suppose to round the first argument to an integer value according to the rounding mode specified by its second argument )

but I get this error

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

testpre.c:22:27: error: 'mode' undeclared (first use in this function)
newcw = cw & 0xf3ff | mode;
^
testpre.c:22:27: note: each undeclared identifier is reported only once for each function it appears in

---------------------------------------------------------------------------------------------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define RND_CTL_BIT_SHIFT 10

// floating point rounding modes: IA-32 Manual, Vol. 1, p. 4-20
typedef enum {
ROUND_NEAREST_EVEN = 0 << RND_CTL_BIT_SHIFT,
ROUND_MINUS_INF = 1 << RND_CTL_BIT_SHIFT,
ROUND_PLUS_INF = 2 << RND_CTL_BIT_SHIFT,
ROUND_TOWARD_ZERO = 3 << RND_CTL_BIT_SHIFT
} RoundingMode;

// do not change anything above this comment

---------------------------------------------------------------------------------------------------------------------------------------------------------

double roundD(double n, RoundingMode roundingMode)
{
short cw, newcw;

__asm__("fstcw %w0" : "=m" (cw));
newcw = cw & 0xf3ff | mode;
__asm__("fldcw %w0" : : "m" (newcw));
__asm__("frndint" : "+t" (n));
__asm__("fldcw %w0" : : "m" (cw));
return n;
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

double hullSpeed(double lgth)
{
   double result;
__asm__(
"fldl %1 " //st(0)=>st(1), st(0)=lgth
"fsqrt " //st(0) = square root st(0)
"fmulp " //Multiplies st(0) and st(1) (1.34)
: "=&t" (result) : "m" (lgth), "f" (1.34) );
return result;
}

// do not change anything below this comment, except for printing out your name

double hullSpeedC(double lgth)
{
   // this C implementation of the hull speed computation is provided
   // so you can compare its correct results with the results of your code

   return 1.34 * sqrt(lgth);
}

void printRounded(char *label, RoundingMode roundingMode,
               double lgth, double hullSpd, double hullSpdC)
{
   printf("%s hullSpeed(%.0f) = %.0f, %.0f ",
       label, lgth,
       roundD(hullSpd, roundingMode),
       roundD(hullSpdC, roundingMode));
}

int main (int argc, char **argv)
{
   double   lgth;
   double   hullSpd, hullSpdC;

   printf("CS201 - Assignment 02 - I. Forgot ");
   if (argc != 2) {
       printf("need 1 argument: boat length ");
       return -1;
       }
   lgth = atof(argv[1]);
   hullSpd = hullSpeed(lgth);
   hullSpdC = hullSpeedC(lgth);

   printf("hullSpeed(%.0f) = %.3f, %.3f ", lgth, hullSpd, hullSpdC);
   printRounded("round even:", ROUND_NEAREST_EVEN, lgth, hullSpd, hullSpdC);
   printRounded("round down:", ROUND_MINUS_INF, lgth, hullSpd, hullSpdC);
   printRounded("round up: ", ROUND_PLUS_INF, lgth, hullSpd, hullSpdC);
   printRounded("round zero:", ROUND_TOWARD_ZERO, lgth, hullSpd, hullSpdC);

   return 0;
}

Explanation / Answer

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define RND_CTL_BIT_SHIFT   10

// floating point rounding modes: IA-32 Manual, Vol. 1, p. 4-20
typedef enum {
    ROUND_NEAREST_EVEN =    0 << RND_CTL_BIT_SHIFT,
    ROUND_MINUS_INF =       1 << RND_CTL_BIT_SHIFT,
    ROUND_PLUS_INF =        2 << RND_CTL_BIT_SHIFT,
    ROUND_TOWARD_ZERO =     3 << RND_CTL_BIT_SHIFT
} RoundingMode;

// do not change anything above this comment

//--------------------------------------------------------------------------------------------------

//-------------------------------------------------------

double roundD(double n, RoundingMode roundingMode)
{
short cw, newcw;

    __asm__("fstcw %w0" : "=m" (cw));
    newcw = cw & 0xf3ff | roundingMode;//in this statement you typed it as mode it must be roundingMode
    __asm__("fldcw %w0" : : "m" (newcw));
    __asm__("frndint" : "+t" (n));
    __asm__("fldcw %w0" : : "m" (cw));
    return n;
}

//--------------------------------------------------------------------------------------------------//-------------------------------------------------------------------------

double hullSpeed(double lgth)
{
     double result;
    __asm__(
            "fldl %1 " //st(0)=>st(1), st(0)=lgth
            "fsqrt "   //st(0) = square root st(0)
            "fmulp "   //Multiplies st(0) and st(1) (1.34)
            : "=&t" (result) : "m" (lgth), "f" (1.34) );
    return result;
}

// do not change anything below this comment, except for printing out your name

double hullSpeedC(double lgth)
{
    // this C implementation of the hull speed computation is provided
    // so you can compare its correct results with the results of your code

    return 1.34 * sqrt(lgth);
}

void printRounded(char *label, RoundingMode roundingMode,
                  double lgth, double hullSpd, double hullSpdC)
{
    printf("%s hullSpeed(%.0f) = %.0f, %.0f ",
           label, lgth,
           roundD(hullSpd, roundingMode),
           roundD(hullSpdC, roundingMode));
}

int main (int argc, char **argv)
{
    double    lgth;
    double    hullSpd, hullSpdC;

    printf("CS201 - Assignment 02 - I. Forgot ");
    if (argc != 2) {
        printf("need 1 argument: boat length ");
        return -1;
        }
    lgth = atof(argv[1]);
    hullSpd = hullSpeed(lgth);
    hullSpdC = hullSpeedC(lgth);

    printf("hullSpeed(%.0f) = %.3f, %.3f ", lgth, hullSpd, hullSpdC);
    printRounded("round even:", ROUND_NEAREST_EVEN, lgth, hullSpd, hullSpdC);
    printRounded("round down:", ROUND_MINUS_INF,    lgth, hullSpd, hullSpdC);
    printRounded("round up: ", ROUND_PLUS_INF,     lgth, hullSpd, hullSpdC);
    printRounded("round zero:", ROUND_TOWARD_ZERO, lgth, hullSpd, hullSpdC);

    return 0;
}

The following assembly code generated.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote