'Break down the logic for a C for-loop into something I can implement in MIPS? (count number occurrences in an array)

Hi all i am converting my C code to MIPS but problem is here i couldn't make correct logic for this

for (int i=0;i<count;i++)
  {
        h[a[i]]++;
  }

as far i make my own logic that is wrong

Assume That

a[]=$t1 b[]=$t2

li $s1,0

for:
bgt $s1,[size of array],end

lw $t3,($t1)
la $t1,4($t3)
lw $t4,($t2)
la $t2,4($t2)
sw $t3,0($t4)

add $s1,$s1,1
j for

i know this is wrong .. but in MIPS it gives me bad address error and exception 7 and 4 error


Also, how to get the array length into a MIPS register, like how C can calculate the number of elements for you without having to hard-code it?

int arr[]={1,3,5,7,9};
int n=sizeof(arr)/sizeof(arr[0]);


Solution 1:[1]

You need to understand what is being incremented.  One approach to gaining this understanding is decomposition: expressions can be decomposed using an approach like Three-Address Code.

Suggest then, to decompose this:

    h[a[i]]++;

as follows:

    int av = a[i];
    h[av]++;

In this approach, we separate various operations & elements of the expression into their own lines of code, and reconnect them using an introduced variable, aka a temporary or short-lived variable.

and we can continue decomposition:

    int av = a[i];

    // decompose h[av]++;
    int *hp = h + av; 
    *hp = *hp + 1;

and yet still:

    int av = a[i];

    int *hp = h + av;

    // decompose *hp = *hp + 1;
    int  hv = *hp;
    hv++;
    *hp = hv;

That's about as decomposed as can be.  Hopefully, you can (1) translate that into MIPS assembly and (2) learn of the technique of decomposition.


Note that in the C language, when an array, a has int elements, in an expression such as a + i and h + j there is a hidden multiplication of the index (i and j) by sizeof(int), i.e. 4, called scaling that occurs before the addition — this scaling, automatic in C, must be explicitly done in assembly.


Control structures, i.e. structured statements can also be decomposed:

for (i = 0; i < count; i++) {
    ???
}

first decomposition:

i = 0;
while (i < count) {
    ???
    i++;
}

and further into if-goto-label style:

    i = 0;
loop1:
    if (i >= count) goto endLoop1;
    ???
    i++;
    goto loop1;
endLoop1:

Notice how the loop exit condition is inverted (negated) — this because in if-goto-label, we are writing when to exit the loop rather than when to continue the loop as in C for/while, which represents the exact opposite.

(This is not always the case: a do-while condition says when to continue the loop as well, and in assembly, since that is the natural place to put the backward branch for the next iteration of the loop, the condition test for do-while and if-goto-label versions will have the same condition sense — they are not opposites — whereas a repeat-until in Pascal uses the opposite condition sense.)

Also NB: the inversion/negation/opposite of   <   is   >= .


Decomposition is simplification by transformations of logical equivalence.  As long as we maintain logical equivalence, the decomposition will run the same as the original.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1