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.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.