user222731
user222731

Reputation:

MIPS Assembly assignment HELP!

My closest friend is going through an EE course (I'm his last hope : /), I have knowledge of Java from about 7 years ago, but his (outline) latest EE programming assignment is to use the MIPS Assembly to do the following:

Write a program that takes two positive integers (m and n) and computes:

x= (m^n) - (1+2+3+…+n) * min(m,n)!

Both the integers should be greater than zero. I'm not allowed to use any R-type arithmetic instructions (add, mult, sub). Instead I'm to write the code for their functions using other instructions???? "Your program should continue getting new values for m and n after each computation until the user enters zero which would be the end for your program."

I do not have access to any of his previous assignments and trying to dive head 1st into assembly language WITHOUT using (add, mult, sub) isn't working out for me too well.

ece.ucdavis.edu/~vojin/CLASSES/EEC70/W2001/pr4.pdf Prof seemed to be using an ols assignment from when he was teaching at UC Davis.

//edit Here is a c++ version of the problem, it does not cover all of the assignment's bases, but it's a starting point:

#include <iostream.h>

//x = (m^n) - (1+2+3+...+n) * ((min(m,n))!)
int m; //User Input
int n; //User Input
double answer; //Answer yo.

int findMin(int, int); //Takes 2 int inputs and outputs the smallest int.
int minFound; //Function output

double factorial(int); //Do eet.
double factOutput; //Function output

double sumN(int); //1+2+3+...+n
double sumFound; //Function output

double expMtoN(int, int); //m^n, float for number size,
double expFound; //Function output, float for number size,

int main(void)
{
    cout << "Please enter a positive integer (m): ";
    cin >> m;

    //Escape if zero.
    if ( m == 0)
    {
        cout << "User input for \"m\" is equal to zero; escape on zero." << endl;
        return 0;
    }

    cout << "Please enter a positive integer (n): ";
    cin >> n;

    //Escape if zero.
    if ( n == 0)
    {
        cout << "User input for \"n\" is equal to zero; escape on zero." << endl;
        return 0;
    }

    expFound   = expMtoN(m, n);       //m^n
    sumFound   = sumN(n);             //1+2+3+...+n
    minFound   = findMin(m, n);       //Takes 2 int inputs and outputs the smallest int.
    factOutput = factorial(minFound); //Factorial math for minFound (z!)

    answer = expFound - sumFound * factOutput; //x = (m^n) - (1+2+3+...+n) * ((min(m,n))!)

    cout << endl;
    cout << m << " raised to the power of " << n << " is: " << expFound << endl;
    cout << "Sum of " << n << " is: " << sumFound << endl;
    cout << "Lowest number out of " << m << " and " << n << " is: " << minFound << endl;
    cout << minFound << " factorial is: " << factOutput << endl;

    cout << endl << "x = (m^n) - (1+2+3+...+n) * ((min(m,n))!)" << endl;
    cout << "x = " << answer << endl;
}

//all temp variables below are confined to their respective functions.
//return functions output temp into variable from main.

double expMtoN(int userBase, int userExp)
{
    double temp = 1; //Must establish  1 so you are not multiplying by zero.

    for ( int i = 1; i <= userExp; i++ )
        temp *= userBase;

    return temp;
}

double sumN(int userN)
{
    double temp = 0;

    for ( int i = 1; i <= userN; i++ )
        temp = temp + i;

    return temp;
}

int findMin(int userM, int userN)
{
    if( userM <= userN )
        return userM;
    else
        return userN;
}

double factorial(int minFound)
{
    double temp;

    if ( minFound <= 1 )
        return 1;

    temp = minFound * factorial(minFound - 1);

    return temp;
}

Input.s


;-----------------------------------------------------------------------------
;Subprogram call by symbol "InputUnsigned"
;expect the address of a zero-terminated prompt string in R1
;returns the read value in R1
;changes the contents of registers R1,R13,R14
;-----------------------------------------------------------------------------

  .data

  ;*** Data for Read-Trap
ReadBuffer: .space  80
ReadPar: .word  0,ReadBuffer,80

  ;*** Data for Printf-Trap
PrintfPar: .space  4

SaveR2:  .space  4
SaveR3:  .space  4
SaveR4:  .space  4
SaveR5:  .space  4


  .text

  .global  InputUnsigned
InputUnsigned: 
  ;*** save register contents
  sw  SaveR2,r2
  sw  SaveR3,r3
  sw  SaveR4,r4
  sw  SaveR5,r5

  ;*** Prompt
  sw  PrintfPar,r1
  addi  r14,r0,PrintfPar
  trap  5

  ;*** call Trap-3 to read line
  addi  r14,r0,ReadPar
  trap  3

  ;*** determine value
  addi  r2,r0,ReadBuffer
  addi  r1,r0,0
  addi  r4,r0,10 ;Decimal system

Loop:  ;*** reads digits to end of line
  lbu  r3,0(r2)
  seqi  r5,r3,10 ;LF -> Exit
  bnez  r5,Finish
  subi  r3,r3,48 ;´0´
  multu  r1,r1,r4 ;Shift decimal
  add  r1,r1,r3
  addi  r2,r2,1  ;increment pointer
  j  Loop

Finish:  ;*** restore old register contents
  lw  r2,SaveR2
  lw  r3,SaveR3
  lw  r4,SaveR4
  lw  r5,SaveR5
  jr  r31  ; Return 

Upvotes: 1

Views: 3789

Answers (1)

chrislgarry
chrislgarry

Reputation: 616

Unfortunately, if that is the C code, then the MIPS code will be at least 4X longer than that and much longer given the restrictions. This code may take a while but I can give a pseudo walk-through:

x = (m^n) - (1+2+3+…+n) * min(m,n)!

Let's first note, like in any other programming language, we should divide our task into as many methods as possible. In MIPS, we want to divide the task into as many "procedures" (labels) as possible. We can already see that we will need a procedure for exponential, factorials, etc. We start with m^n. We can't use mult since it is R-type, but we can use multi, which is I-type. We can use all of the immediate I-types as substitutes for this assignment. So we could do: multi m,m for example in a for loop and do this n times, giving m^n (in each iteration we would have move the results from the multiply registers Hi and Lo, using the instructions mfhi and mflo, for calculation so they don't get overwritten). This would be our first procedure.

Now we look at the 1+2+3+...+n. This is not too bad, we just keep using addi (an add instruction of type-I that adds "immediate" constants to a register) such as addi $s1,$s1,b, where a is 1, which is incremented in a loop and added to the result n times, thus getting 1+2+3+...+n.

Finally, we need another procedure to multiply this by min(m,n)!. Factorial is recursive, so we'll need a recursive procedure that calls itself and makes good use of the memory stack and register spilling (IE first saving the procedure arguments and return address onto the stack, enter the body, the call itself again). I think this is enough to get you started. Not sure when the assignment is due but good luck!

Upvotes: 2

Related Questions