【发布时间】:2016-10-02 20:34:36
【问题描述】:
我是 MIPS 的新手,正在尝试编写 Wikipedia 中描述的埃拉托色尼筛算法来查找从 1 到 1000 的所有素数。我只是按照 1-4 中概述的步骤进行操作,但还没有所描述的任何改进。
到目前为止,这是我的代码:
.data
array: .word 1:1000 # array[1000] = {1} (assume all are prime initially)
length: .word 1000
.text
.globl main
main: addi $t0, $zero, 1 # $t0 = 1 (counter)
la $s0, length # $s0 = &length
lw $s0, 0($s0) # $s0 = length
la $t1, array # $t1 = &array[0]
lw $t2, 0($t1) # $t2 = array[0]
addi $t2, $t2, -1 # $t2 = 0
sw $t2, 0($t1) # array[0] = $t2 = 0 (1 is not prime)
loop1: beq $t0, $s0, ToDo # if counter == length...
addi $t0, $t0, 1 # counter++
addi $t1, $t1, 4 # $t1 = &array[counter]
lw $t2, 0($t1) # $t2 = array[counter]
beq $t2, 0, loop1 # if $t2 is marked as not prime, move to next element
addi $t3, $zero, 1 # $t3 = 1 (multiplier)
addi $t4, $t0, 0 # $t4 = counter (p)
loop2: addi $t3, $t3, 1 # multiplier++
mul $t4, $t4, $t3 # $t4 = $t4 * multiplier (2p, 3p, 4p...)
bgt $t4, $s0, loop1 # if $t4 >= length, go to outer loop
la $t5, $t4($t1)
ToDo:
我知道我的最后一行无效。我试图在 2p、3p、4p 等的每个索引处访问数组,并将它们的值设置为0(不是素数)。我怎么能以其他方式做到这一点?如何在循环的每次迭代中访问不同索引处的数组?
编辑
这是我在查看以下 Craig 的答案后的最终解决方案: (为糟糕的缩进道歉 - 我的编辑器没有很好地复制它)
.data
array:
.word 1:1000 # array of 1000 '1's - 1 = prime, 0 = not prime
length:
.word 1000 # length of array
primeArray:
.word 0:200 # array of size 200 to store primes
.text
.globl main
main: addi $s0, $zero, 0 # counter = 0
la $s1, length # s1 = &length
lw $s1, 0($s1) # s1 = length
la $t0, array # t0 = &array[0]
sw $zero, 0($t0) # array[0] = 0 -> '1' is not prime
outerLoop:
beq $s0, $s1, gatherPrimes # if counter == length
addi $s0, $s0, 1 # counter++
addi $t0, $t0, 4 # t0 = &array[counter]
lw $t1, 0($t0) # t1 = array[counter]
beq $t1, $zero, outerLoop # if array[counter] is already not prime, continue
addi $t2, $s0, 1 # t2 = counter + 1
addi $t3, $t2, 0 # t3 = t2
innerLoop:
add $t3, $t3, $t2 # t3 = t3 + t2
bgt $t3, $s1, outerLoop # if t3 > length, break
addi $t4, $t3, -1 # t4 = t3 - 1
la $t5, array # t5 = &array[0]
sll $t6, $t4, 2 # t6 = t4 * 4 (offset)
add $t5, $t5, $t6 # t5 = &array[t3]
sw $zero, 0($t5) # array[t3] = 0 -> not prime
j innerLoop
gatherPrimes:
addi $s0, $zero, 0 # counter = 0
addi $s2, $zero, 0 # primeCounter = 0
la $t0, array # t0 = &array[0]
la $t2, primeArray # t2 = &primeArray[0]
loop:
beq $s0, $s1, exit # if counter == length, exit
lw $t1, 0($t0) # t1 = array[counter]
addi $s0, $s0, 1 # counter++
addi $t0, $t0, 4 # t0 = &array[counter]
beq $t1, $zero, loop # if array[i] is not prime, break
sw $s0, 0($t2) # primeArray[primeCounter] = counter
addi $s2, $s2, 1 # primeCounter++
addi $t2, $t2, 4 # t2 = &primeArray[primeCounter]
j loop
exit:
syscall
【问题讨论】:
标签: arrays mips sieve-of-eratosthenes mips32 sieve