0
votes

Hi so I am brand new to the whole MIPS assembly code and am trying to teach myself with online help sources. I can understand some parts of it and how it works. My problem that I need to solve now is

int A[50], B[50]; 
for (i=1; i < 50; i++) { 
 A[i] = A[i] + B[i-1] / A[i-1]; 
}

Some tips and pointers would very much be appreciated looking to expand my knowledge. I've tried those online things but don't seem to help me learn.

1
I've tried those online things but don't seem to help me learn - so what do you expect to get here? By "online things" you mean some online c-to-mips translators? - Eugene Sh.
You can have a look at how compilers translate your code into assembly. Don’t forget to turn optimizations off, otherwise any compiler will optimize the heck of your code) - ForceBru
@EugeneSh. Yes the c-mips. In not looking for someone to do it for me, some people are new to this (me) and so i dont think the attitude is needed. Just looking for what would be my best bet going about this - Daniel R
Looking at compiler output is usually your best bet. @ForceBru: There's not much to optimize here, and -O0 code is really noisy and hard to follow (full of store/reload). godbolt.org/z/RbYSsR from gcc (for MIPS II) and clang (for MIPS32r6) are pretty reasonable. The teq is a trap-on-equal to catch division by zero. If targeting baseline MIPS I, it uses a conditional branch over a break instruction. - Peter Cordes

1 Answers

1
votes

Here is how the compilers translate this kind of code.
This is C code, but it is strictly equivalent to your original code and it is written in such a way that every C instruction can be mapped to an asm instruction. I have even written which instruction should be used.

int * pA=&A[0];     // mov
int * pB=&B[0];     // mov
int i=1;            // addi
int n=50;           // addi
do{
  // body of for loop
  int B_1=*(pB-1) ; // lw
  int A_1=*(pA-1) ; // lw
  int D=B_1/A1;     // div
  int A=*pA;        // lw
  A += D;           // add
  *pA = A;          // sw
  // increment part of the loop
  i+=1;             // addi
  pA+=1;            // addi
  pb+=1;            // addi
  // test part of the loop
  while (i<N);      // blt -> do
 }

You just have to pick a register for all the variables (for instance, choose to copy pA in $t3 (or r4 or whatever), and figure out how to translate this instruction in asm. Look at MIPS documentation and translation should be easy.

There are though a couple of important things to know.

  1. Pointers are similar to memory addresses that are manipulated by the processor, except when increment (or in general pointer arithmetic) is concerned. If p is a pointer to an element of type T in C, p++ means that p will point to the next element of type T. For adresses, the size of the type must be considered. If an int is 4 bytes, "point to next int" will correspond to "add to address the size of an int" (ie 4).

  2. lw and sw use based addressing, that is they can add an immediate to an address. Pointer arithmetic is also relevant. So if p is an int pointer, and you want to implement x=*(p+2), assuming x is in $t4 and p is in $t7, you have to do lw $t4,8($t7) that means read memory at address $t7+8 (as 8==2*sizeof(int).

It should not be too difficult to write a first code. Then, you can try to optimize it. Maybe loading A[i-1] at every iteration is not useful, for instance? Maybe you can reduce the number of variables (registers)?