0

I'm working on translating the below C++ code to MIPS (this is just a small portion of the program that I'm stuck on), and I understand the gist of how to set $t registers to take the array values given, but I'm completely stuck on

pos[count] = i;

I've tried sw, lw, but everytime I try these, I get address out of range exceptions/etc.

Can someone explain to me what's going wrong here? When the loop gets to pos[count] = i, I need to change pos[count] from 0xffffffff to (i) for each loop iteration. Is the error coming because I need to adjust for the -1's in pos[] ?

I'm completely lost and haven't been able to find any explanations that are similar enough to this problem.

(Apologies for the formatting, because MIPS has so many tabbed lines, the formatting for posting here is exceptionally wacky)

    .data
x:  .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
pos:    .word   -1
        .word   -1
        .word   -1
        .word   -1
        .word   -1
        .word   -1
        .word   -1
        .word   -1
        .word   -1
        .word   -1
d:      .word   73
        .word   47
        .word   23
        .word   26
        .word   67
        .word   99
        .word   13
        .word   53
        .word   1
        .word   97

sp: .asciiz " "
endl:   .asciiz "\n"

# $s0   count
# $s1   key
# $s2   i

        .text

main:   addi    $s0, $0, 0  #  int count = 0;
        addi    $s1, $0, 24         #  int key = 24;
        addi    $s2, $0, 0
        la  $s3, d
        la  $s4, pos
        la  $s5, x
                       #  for (int i=0; i<10; i++) {
loop:   mul     $t0, $s2, 4 #    if (d[i] >= key) {
        add     $t0, $t0, $s3
        lw  $t0, ($t0)

            blt     $t0, $s1, loop1

            sll     $t1, $s0, 2     # $t1 = count * sizeof(int)
            addu    $t2, $s4, $t1   # $t2 = &pos[count];
            lw      $t2, ($t2)  # $t2 = pos[count];

            add     $t3, $s5, $t1   # $t3 = &x[count];
            lw      $t3, ($t3)  # $t3 = x[count];


            sw    $s2, ($t2)            #      pos[count] = i;
                    #      x[count] = d[i];

loop1:     addi    $s2, $s2, 1     # i++;
           addi    $s0, $s0, 1     # count++;
                    #    }
                    #  }

Here's the C++ code equivalent:

#include <iostream>
using namespace std;

int x[10] = {0};
int pos[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
int d[10] = {73, 47, 23, 26, 67, 99, 13, 53, 1, 97};
int main() {

int count = 0;
int key = 24;
for (int i=0; i<10; i++) {
   if (d[i] >= key) {
     pos[count] = i;
     x[count] = d[i];
      count++;
  }
 }

for (int i=0; i<10; i++) {
    if (pos[i] < 0)
      break;
     cout << pos[i] << " " << x[i] << endl;
    }

 }
2
  • I can't make heads or tails of this. It would be helpful if you showed what C++ code you are trying to duplicate, and then we would know what this is supposed to do. Commented Sep 30, 2013 at 20:16
  • Gotcha. I just added the C++ equivalent more clearly at the bottom of the post. My main problem is translating pos[count] = i; and x[count] = d[i]; to MIPS Commented Sep 30, 2013 at 20:55

2 Answers 2

2

This part is wrong:

lw      $t2, ($t2)  # $t2 = pos[count];
add     $t3, $s5, $t1   # $t3 = &x[count];
lw      $t3, ($t3)  # $t3 = x[count];
sw    $s2, ($t2)    #      pos[count] = i;

Why are you loading pos[count] and x[count] when you want to write to both? Not only is this unnecessary, it will destroy $t2 and $t3 so when you really want to write, they will no longer be valid.

Also, the end of the loop is wrong, the count++ should be inside the condition. For that you will need to swap the last two lines (including the label).

A slightly cleaned up version could look like:

    .data
x:      .word   0, 0, 0, 0, 0, 0, 0, 0, 0, 0
pos:    .word   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
d:      .word   73, 47, 23, 26, 67, 99, 13, 53, 1, 97

# $s0   count
# $s1   key
# $s2   i

        .text
.globl main
main:   addi    $s0, $0, 0      #  int count = 0;
        addi    $s1, $0, 24     #  int key = 24;
        addi    $s2, $0, 0      #  int i = 0;
#  for (int i=0; i<10; i++) {
loop:   sll     $t0, $s2, 2     # $t0 = i * sizeof(int)
        lw      $t0, d($t0)     # $t0 = d[i]
        blt     $t0, $s1, loop1 # if (d[i] < key)

        sll     $t1, $s0, 2     # $t1 = count * sizeof(int)
        sw      $s2, pos($t1)   # pos[count] = i
        sw      $t0, x($t1)     # x[count] = d[i]
        addi    $s0, $s0, 1     # count++;

loop1:  addi    $s2, $s2, 1     # i++;
        blt $s2, 10, loop
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much, you don't know how grateful I am. Been tinkering with this problem now for about two days straight. The load part I was given in the problem setup, so I thought I was stuck using only that type of loading an address: thus, I didn't know you could do d($t0), for example.
On the vein of cleaning up, may I suggest x: .word 0:10 y: .word -1:10
0

int count(int a[], int n, int x){ int res = 0; int i = 0; for(i = 0; i != n; i++) if(a[i] == x) res = res + 1; return res; }

Write a MIPS assembly program that will make use of the function count above as follows:  Hard-code the following 10 values into array a: 128, 10, 23, 12, 128, 9, 220, 46, 128, 5  Hard-code n = 10  Prompt the user to enter a value as follows: “Please enter an integer value”  Read the integer value and store it (lets call it x)  Call the function count with the following arguments: count(a, 10, x)  Output the results as follows: “The number of times x appears in the list is res times”  Exit the program

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.