2010-02-26 22 views
8

bất kỳ ý tưởng nào? Tại sao tôi nhận được: Runtime ngoại lệ tại 0x00400020: lấy địa chỉ không phù hợp trên ranh giới từ dòng 0x00000007 Vấn đề là: lw $ s1,0 ($ a1) #copy arg2 = kích thước của mảngMIPS tìm nạp địa chỉ không được căn chỉnh trên ranh giới từ, được sử dụng .align 4, vẫn không đi

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

Trả lời

7

Vấn đề với mã là, rằng bạn không sử dụng địa chỉ nơi kích thước được lưu trữ nhưng kích thước thân:

Ở đây bạn tải địa chỉ vào A0 và kích thước (7) vào A1:

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

đây bạn tải từ đầu tiên được lưu trữ tại mảng của bạn sẽ tải 10). Đây không phải là những gì bạn đã dự định.

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

Tại đây bạn tải từ đầu tiên được lưu trữ tại vị trí 0x000007. (kích thước của bạn). Đây có lẽ cũng không có ý định và sẽ gây ra một ngoại lệ vì địa chỉ không thẳng hàng:

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

và vân vân.

Dường như với tôi, bạn hiểu nhầm lệnh LW làm gì. Nó đọc một vị trí bộ nhớ vào một thanh ghi. Những gì bạn muốn trong prolog của vòng lặp của bạn là tạo bản sao của một thanh ghi.

Để làm như vậy, bạn có thể sử dụng lệnh di chuyển giả nếu trình biên dịch của bạn hỗ trợ nó. Nếu không sử dụng các hướng dẫn OR để sao chép ghi như thế này:

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: 

      ... 

cho một ví dụ hoàn chỉnh của một vòng lặp tìm kiếm tuyến tính thử này (chưa được kiểm tra và hy vọng rằng lắp ráp quan tâm đến các khe chậm trễ)

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, Tôi thực sự đánh giá cao sự giúp đỡ. Đây không phải là một tìm kiếm tuyến tính, nó chỉ là một vấn đề từ một cuốn sách có thêm một số khác, nhưng điều đó không liên quan. Tôi đã quay lại và nhận thấy một vài lỗi, nhưng tôi vẫn gặp sự cố. Các vấn đề của tôi đã xoay quanh vấn đề này: la $ a0, mảng \t #if điều này tải địa chỉ của mảng vào a0 và lw $ s0, ($ a0) # sẽ không sao chép địa chỉ được lưu tại đó đến s0 Tôi đã sửa điều này trong mã của tôi bằng cách thực hiện la $ s0, ($ a0) Cách tôi hiểu LW là nó nhận được giá trị được lưu trữ tại địa chỉ bộ nhớ đó và đặt nó vào thanh ghi. Vậy điều này có đúng không? Nó chỉ lưu trữ địa chỉ? – bep

+0

la tải địa chỉ của một biểu tượng. Trong trường hợp của bạn, nó sẽ chứa vị trí của phần tử mảng đầu tiên. lw tải ô nhớ từ bộ nhớ và lưu nó vào thanh ghi đích. la $ s0, ($ a0) không có ý nghĩa. la luôn lấy một biểu tượng từ mã của bạn, không bao giờ là một thanh ghi. –

Các vấn đề liên quan