tags:

views:

519

answers:

1

any ideas? Why I am getting: Runtime exception at 0x00400020: fetch address not aligned on word boundary 0x00000007 Problem line is: lw $s1,0($a1) #copy arg2 = size of array

.data
    .align 4 #added this, didnt work
    size:   .word   7
    .align 4 #added this, didnt work
    search: .word   30
    .align 4 #added this,didnt work
    array:  .word 10,20,30,40,50,60,70
    .align 4

.text

main:

            la  $a0,array   #$a0 = address of array
            lw  $a1,size    #a1 = size of array
            lw  $a2,search  #$a2 = search key


COUNT:
            lw $s0,0($a0)   #copy arg1 = address array
            addi $s1,$zero,7
            lw $s1,0($a1)   #copy arg2 = size of array
            lw $s2,0($a2)   #copy arg3 = search key (n)
            addi $s2,$zero,30
            COUNTLOOP:
            add $v0,$zero,$zero #v0 = res
            add $t0,$zero,$zero #$t0 = init i to 0
            slt $t1,$t0,$s1     #check if i > size of array
            beq $t1,$zero,DONECOUNT #i is n so end
            sll $t2,$s0,2       #$t2 = get off set for a[i]
            lw  $t3,0($t2)      #$t3 = get value of a[i]
            bne $t3,$s2,CLOOPBTM #check if a[i] == seach key
            addi $v0,$v0,1      #if above then increment res
            CLOOPBTM:
            addi $t0,$t0,1
            j COUNTLOOP
            DONECOUNT:
+1  A: 

The problem with the code is, that you're not using the address where the size is stored but the size itself:

Here you load the address into A0 and the size (7) into A1:

        la  $a0,array   
        lw  $a1,size    #a1 = size of array

Here you load the first word stored at your array (that will load a 10). This is not what you've intended.

        lw $s0,0($a0)   #copy arg1 = address array
        addi $s1,$zero,7

Here you load the first word stored at location 0x000007. (your size). This is probably also not intended and will cause an exception because the address is not aligned:

        lw $s1,0($a1)   #copy arg2 = size of array

and so on.

It seems to me, that you have a misunderstanding what the LW instruction does. It reads a memory location into a register. What you want in the prolog of your loop is to make copies of a register.

To do so you can use the move pseudo instruction if your assembler supports it. Otherwise use the OR instruction to copy registers like this:

COUNT:
            or    $s0, $a0, $a0   #copy arg1 = address array
            addi  $s1, $zero,7
            or    $s1, $a1, $a1   #copy arg2 = size of array
            or    $s2, $a2, $a2   #copy arg3 = search key (n)
            addi  $s2, $zero,30
            COUNTLOOP:

            ...

for a complete example of a linear search loop try this (untested and expects that the assembler cares about the delay slots)

main:

            la  $a0,array            # $a0 = address of array
            lw  $a1,size             # $a1  = size of array
            lw  $a2,search           # $a2 = search key


            beq $a1, $zero, NOTFOUND # handle the size==0 case..
            or  $v0, $zero, $zero    # init counter to zero

LOOP:
            lw  $s0, 0($a0)          # load element
            beq $s0, $a2, FOUND      # branch if key found:

            addiu $a0, $a0, 4        # increment array pointer
            addiu $v0, $v0, 1        # increment loop counter
            bne   $v0, $a1, LOOP     # repeat until we've processed the array.

NOTFOUND:
            # --------------------------------------
            # if you reach this, key does not exist:
            # --------------------------------------
            li  $v0, -1              # load a -1 to signal key not found.
            jr  $lr                  # return to caller

FOUND:
            # -----------------------------------------
            # v0 now contains the position of the key.
            # -----------------------------------------
            jr  $lr
Nils Pipenbrinck
Hey, I REALLY appreciate the help. This isn't quite a linear search, its just a problem from a book that adds another number, but that is irrelevant. I did go back and notice a few mistakes, but I was still have problems. My problems have revolved around this:la $a0,array #if this loads the address of the array into a0 andlw $s0,($a0) #should this not copy the address stored there to s0I fixed this in my code by doing la $s0,($a0)The way I understood LW is it gets the value stored at that memory address and puts it in the register. So is this incorrect? It just stores the address?
bep
la loads the address of a symbol. In your case it will contain the location of the arrays first element. lw loads the memory cell from memory and stores it in the destination register.la $s0, ($a0) makes no sense. la always takes a symbol from your code, never a register.
Nils Pipenbrinck