2016-09-22 20 views
0

いくつかのコードに問題があります。私は練習しています。私の人生のために、自分のコードに何が間違っているのか分からないようです。私は続ける "存在しないメモリを使用しようとしました"というエラーが発生し、is_primeを呼び出した後、88行目の関数/ラベルに戻るときにエラーが発生したようです。存在しないメモリMIPSを使用しようとしました

何か助けていただければ幸いです。私はこれを数時間過ごしましたが、まだ理解できません。ここで

はコードがあなたのコードにはいくつかの問題があります

# 
# CONSTANT DECLARATIONS 
# 
PRINT_INT = 1  # code for syscall to print integer 
PRINT_STRING = 4  # code for syscall to print a string 
MIN  = 3  # minimum value to check 
MAX  = 102  # max value to check 

# 
# DATA DECLARATIONS 
# 
    .data 
newline: 
    .asciiz "\n" 
# 
# MAIN PROGRAM 
# 
    .text 
    .align 2 
    .globl main 
main: 
     addi $sp,$sp,-8  # space for return address/doubleword aligned 
     sw  $ra, 0($sp)  # store the ra on the stack 

    jal find_primes 

     # 
     # Now exit the program. 
    # 
     lw  $ra, 0($sp) # clean up stack 
     addi $sp,$sp,8 
     jr  $ra 

# 
# Name:  find_primes 
# 
# Description: find the prime numbers between 3 and 101 inclusive 
# Arguments: none 
# Returns: nothing 
# 

find_primes: 
     addi $sp,$sp,-40  # allocate stack frame (on doubleword boundary) 
     sw  $ra, 32($sp) # store the ra & s reg's on the stack 
     sw  $s7, 28($sp) 
     sw  $s6, 24($sp) 
     sw  $s5, 20($sp) 
     sw  $s4, 16($sp) 
     sw  $s3, 12($sp) 
     sw  $s2, 8($sp) 
     sw  $s1, 4($sp) 
     sw  $s0, 0($sp) 


    li $a0, MIN  # load imm 3 into $a0 
loo: 
    slti $t0, $a0, MAX  # if $a0 < 102 set $t0 = 1, else 0 
    beq $t0, $zero, fin  # exit when done 
    j is_prime  # goto func to determine if prime 

    addi $a0, $a0, 1  # **ERROR HAPPENS HERE** 
    j loo   # go back to loop 
fin: 


     lw  $ra, 32($sp) # restore the ra & s reg's from the stack 
     lw  $s7, 28($sp) 
     lw  $s6, 24($sp) 
     lw  $s5, 20($sp) 
     lw  $s4, 16($sp) 
     lw  $s3, 12($sp) 
     lw  $s2, 8($sp) 
     lw  $s1, 4($sp) 
     lw  $s0, 0($sp) 
     addi $sp,$sp,40  # clean up stack 
    jr $ra 

# 
# Name:  is_prime 
# 
# Description: checks to see if the num passed in is prime 
# Arguments: a0 The number to test to see if prime 
# Returns: v0 a value of 1 if the number in a0 is prime 
#   a value of 0 otherwise 
# 

is_prime: 
     addi $sp,$sp,-40  # allocate stackframe (doubleword aligned) 
     sw  $ra, 32($sp) # store the ra & s reg's on the stack 
     sw  $s7, 28($sp) 
     sw  $s6, 24($sp) 
     sw  $s5, 20($sp) 
     sw  $s4, 16($sp) 
     sw  $s3, 12($sp) 
     sw  $s2, 8($sp) 
     sw  $s1, 4($sp) 
     sw  $s0, 0($sp) 

    li $t2, 2   # load 2 into $t2 
    div $a0, $t2  # divide $a0/$t2 -> hi = $a0%$t2 
    mfhi $t1   # load hi reg into $t1 
    beq $t1, $zero, notPri # if $t1 == 0, jump to notPrime 
    li $s0, MIN  # load 3 into $s0 
loopPr: 
    slt $t0, $s0, $a0  # set $t0 to 1 if $s0 < $a0 else 0 
    bne $t0, $zero, notPri # jump to notPri if done looping 
    div $a0, $s0  # divide to get mod $a0%$s0 
    mfhi $t1   # load hi reg value into $t1 
    bne $t1, $zero, prime # if $t1 != 0 it's prime 
    addi $s0, $s0, 1  # increment by 1 since not prime 
    j loopPr   # jump back to loop 
notPri: 
    li $v0, 0   # $v0 = 0 if not prime 
    j dne   # jumpe to done if not prime 
prime: 
    li $v0, 1   # $vi = 1 if prime 
    j print_number 
dne: 


     lw  $ra, 32($sp) # restore the ra & s reg's from the stack 
     lw  $s7, 28($sp) 
     lw  $s6, 24($sp) 
     lw  $s5, 20($sp) 
     lw  $s4, 16($sp) 
     lw  $s3, 12($sp) 
     lw  $s2, 8($sp) 
     lw  $s1, 4($sp) 
     lw  $s0, 0($sp) 
     addi $sp,$sp,40  # clean up the stack 
    jr $ra 

# 
# Name;  print_number 
# 
# Description: This routine reads a number then a newline to stdout 
# Arguments: a0,the number to print 
# Returns: nothing 
# 
print_number: 

     li $v0,PRINT_INT 
     syscall   #print a0 

     la $a0, newline 
     li  $v0,PRINT_STRING 
     syscall   #print a newline 

     jr  $ra 

答えて

1

です。あなたがJALを使用する必要があるときは、Jを使用している場所のカップルで

  • 。 (j is_primeおよびj print_number)。

  • print_numberは、$a0を保存して復元する必要がありますが、そうではありません。

  • プライムチェックが不十分です。 Xが奇数でX%Y!= 0のY < Xが1つ以上ある場合、Xを素数として数えます。 Y < = X/2があります。これはX%Y == 0です(実際にはY < = sqrt(X)までチェックする必要がありますが、平方根関数を書く必要がない場合はX/2で十分です)。

PS:SPIM/MARSには、プログラムの命令ごとのステップ実行を可能にするデバッグ機能があります。私はあなたがそれを使用することを学ぶことをお勧めします。

+0

ありがとうございました!私はMIPSの編集者がいたことは知らなかった。 – Pants

関連する問題