2010-02-26 7 views
8

żadnych pomysłów? Dlaczego otrzymuję: Runtime wyjątek w 0x00400020: pobranie adresu nie wyrównane na linii granicznej słowo 0x00000007 problemem jest: lw $ s1,0 ($ A1) #copy arg2 = wielkość tablicyAdres pobierania MIPS nie jest wyrównany na granicy wyrazów, używany .align 4, nadal nie ma

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

Odpowiedz

7

Problem z kod jest, że nie używasz adresu, gdzie zapisany jest rozmiar ale sam rozmiar:

Tutaj można załadować adres do A0 oraz rozmiar (7) do A1:

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

Tutaj ładujesz pierwsze słowo zapisane w twojej tablicy (to załaduje 10). To nie jest to, co zamierzałeś.

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

Tutaj ładujesz pierwsze słowo przechowywane w lokalizacji 0x000007. (Twój rozmiar). Ten jest prawdopodobnie przeznaczony i nie spowoduje wyjątek, ponieważ adres nie jest wyrównany:

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

i tak dalej.

Wydaje mi się, że nie rozumiesz, co robi instrukcja LW. Czyta lokalizację pamięci w rejestrze. W prologu twojej pętli chcesz zrobić kopie rejestru.

Aby to zrobić, możesz użyć pseudo instrukcji move, jeśli twój asembler ją obsługuje. W przeciwnym razie użyj instrukcję lub skopiować rejestrów tak:

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: 

      ... 

dla kompletnego przykład liniowej pętli wyszukiwania spróbuj tego (niesprawdzone i spodziewa się, że assembler dba o gniazdach opóźnienia)

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 
+0

Hey, NAPRAWDĘ doceniam pomoc. To nie jest wyszukiwanie liniowe, jest to tylko problem z książki, która dodaje inny numer, ale to nie ma znaczenia. Wróciłem i zauważyłem kilka błędów, ale wciąż miałem problemy. Moje problemy kręciły się wokół tego: la $ a0, tablica #if to ładuje adres tablicy do a0 i lw $ s0, ($ a0) # jeśli to nie skopiuje zapisanego tam adresu do s0 Naprawiłem to w moim kodzie wykonując la $ s0, ($ a0) Sposób, w jaki zrozumiałem LW, polega na uzyskaniu wartości przechowywanej pod tym adresem pamięci i umieszczeniu jej w rejestrze. Czy to jest nieprawidłowe? Po prostu przechowuje adres? – bep

+0

la ładuje adres symbolu. W twoim przypadku będzie zawierał lokalizację pierwszego elementu tablicy. lw ładuje komórkę pamięci z pamięci i zapisuje ją w docelowym rejestrze. la $ s0, ($ a0) nie ma sensu. la zawsze bierze symbol z twojego kodu, nigdy nie rejestruje się. –