MIPS-ophaaladres niet uitgelijnd op woordgrens, .align 4 gebruikt, nog steeds niet mogelijk

enig idee? Waarom krijg ik:
Runtime-uitzondering op 0x00400020: ophaaladres niet uitgelijnd op woordgrens 0x00000007
Probleemregel is: lw $s1,0($a1) #copy arg2 = grootte van 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:

Antwoord 1, autoriteit 100%

Het probleem met de code is dat je niet het adres gebruikt waar de maat is opgeslagen, maar de maat zelf:

Hier laad je het adres in A0 en het formaat (7) in A1:

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

Hier laadt u het eerste woord dat op uw array is opgeslagen (die een 10 laadt). Dit is niet wat je bent bedoeld.

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

Hier laad je het eerste woord dat is opgeslagen op locatie 0x000007. (jouw maat). Dit
is waarschijnlijk ook niet bedoeld en zal een uitzondering veroorzaken omdat het adres niet is uitgelijnd:

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

enzovoort.

Het lijkt mij, dat u een misverstand hebt wat de LW-instructie doet. Het leest een geheugenlocatie in een register. Wat u wilt in de PROLOG van uw lus is om kopieën van een register te maken.

Om dit te doen, kunt u de Move Pseudo-instructie gebruiken als uw assembler het ondersteunt. Gebruik anders de of instructie om registers zoals deze te kopiëren:

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:
            ...

Probeer dit voor een compleet voorbeeld van een lineaire zoeklus, probeer dit (niet getest en verwacht dat de assembler om de vertragingsslots geeft)

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

Other episodes