Sauromayne
Sauromayne

Reputation: 105

Simple MIPS for loop not running

I'm very new to MIPs and trying to create a for loop for an assignment.

for (int i=1; i < 16; i+=2) 
{
       A[i] = A[i] + B[3*i]   
} 

With the current code I have when I try to load the value of A[i] it says fetch address not aligned on word boundary.

Here is my code:

main:  
    li      $t0, 1              # Starting index of t0=i 
    lw      $s7, aSize          # Loop bound  
    la      $s0, A              # &A
    la      $s6, endA           # &endA
    la      $s1, B              # &B
loop:
    #TODO: Write the loop code
    addi    $t3, $zero, 3   # $t3 = 3
    mul     $t4, $t0,$t3    # $t4 = i * 3
    sll     $t4, $t4, 2     # $t4 into a byte offset

    add     $s1, $s1, $t4   # $s1 = &B[i*3]
    add     $s0, $s0, $t0   # $s0 = &A[i]

    lw      $t1, 0($s0)     # value of A[i]
    lw      $t2, 0($s1)     # value of B[i * 3]

    add     $t2, $t1, $t2   # A[i] + B[i]
    sw      $t2, 0($s0)     # A[i] = A[i] + B[i]
    addi    $s0, $s0, 2
    addi    $s1, $s1, 2
    addi    $t0, $t0, 1     #i++
    bne     $t0, $s7, loop

I'm very new to MIPs so not sure whats going on or where to even look. I appreciate any help.

Upvotes: 1

Views: 342

Answers (1)

Craig Estey
Craig Estey

Reputation: 33631

When you do:

mul     $t4, $t0,$t3    # $t4 = i * 3

You are calculating the array index [as you would in c].

But, before you can add that to the base address of the array, you need to convert this index into a byte offset. That is, you have to multiply it by 4. This can be done [as in c] with a shift left of 2.

So, after the mul, do:

sll $t4,$t4,2

You have to do this multiply/shift for all index values before adding them in.


UPDATE:

Okay that makes sense. I added that in but I'm still getting that word boundary error on the line "lw $t1, 0($s0)"

You're not showing the definition of A or B, so there could be an alignment issue.

When you do:

add     $s1, $s1, $t4   # $s1 = &B[i*3]

You are modifying the original/base value of &B[0]. That's not what you want. Use a different register for the final address value (i.e. leave $s1 unchanged throughout the loop)

Do something like:

add     $s3, $s1, $t4   # $s3 = &B[i*3]
lw      $t2, 0($s3)     # value of B[i * 3]

Adjust other similar register usage in a similar manner (i.e. you have a similar problem with the A array)

I've coded up a cleaned up version. I've not assembled nor tested it, but I think it will get you closer. This may have an off-by-one error [it's hard to tell without the entire program] as I'm not sure what aSize is.

main:
    li      $t0,1                   # Starting index of t0=i
    lw      $s7,aSize               # Loop bound
    la      $s0,A                   # &A
    la      $s6,endA                # &endA
    la      $s1,B                   # &B
    addi    $t3,$zero,3             # $t3 = 3

loop:
    # TODO: Write the loop code
    mul     $t4,$t0,$t3             # $t4 = i * 3
    sll     $t4,$t4,2               # $t4 into a byte offset
    add     $s3,$s1,$t4             # $s3 = &B[i*3]

    sll     $t4,$t0,2               # $t4 into a byte offset
    add     $s2,$s0,$t4             # $s2 = &A[i]

    lw      $t1,0($s2)              # value of A[i]
    lw      $t2,0($s3)              # value of B[i * 3]

    add     $t2,$t1,$t2             # A[i] + B[i]
    sw      $t2,0($s2)              # A[i] = A[i] + B[i]

    addi    $t0,$t0,2               # i += 2
    bne     $t0,$s7,loop

Upvotes: 1

Related Questions