MIPS汇编代码,用于查找输入数字下方的所有素数
MIPS Assembly code to find all the prime numbers below an inputted number
下面贴出了我的 MIPS 代码。 java 我基于的代码是...
Java代码...
for (int i=2;i<n;i++){
p = 0;
for (int j=2;j<i;j++){
if (i % j == 0)
p = 1;
}
if (p = 0) System.out.println(i);
}
我添加了行 "beq $t3, 1, L4" 以在 p 设置为 1 时跳至 L4 以节省时间。但是当我添加这行代码时,程序没有任何输出。在我添加这一行之前,它会打印 2~n 中的所有整数。
MIPS 代码...
# The number is read through the keyboard
.text
.globl main
main:
# Display message to user for a number
li $v0, 4
la $a0, prompt1
syscall
# read keyboard into $v0 (number x is upper bound number to find primes)
li $v0, 5
syscall
# move the number from $v0 to $t0
move $t0, $v0 # $t0 = n
# store 2 in $t1 and $t2
li $t1, 2 # i
li $t2, 2 # j
L3: # for (int i=2; i<n; i++)
# store 0 in $t3
li $t3, 0 # p = 0;
L2: # for (int j=2; j<i; j++)
# do div of two numbers
div $t2, $t1
# store the remainder in $t4
mfhi $t4
# branch if remainder is not 0 to L1
bne $t4, 0, L1 # if (i % j == 0)
# set $t3 as 1
li $t3, 1 # p = 1
# if p=1 break to next i
beq $t3, 1, L4
L1: # if (i % j == 0)
# add 1 to t2
addi $t2, $t2, 1 # j++
# repeat code while j < i
ble $t2, $t1, L2
# print integer function call 1
# put the answer into $a0
li $v0, 1
move $a0, $t1
syscall # System.out.println(i)
#print comma
li $v0, 4
la $a0, comma
syscall
L4:
# add 1 to t1
addi $t1, $t1, 1 # i++
# repeat code while i < n
ble $t1, $t0, L3 # for (int i=2; i<n; i++)
.data
prompt1:
.asciiz "Enter a number "
comma:
.asciiz ","
我认为发生错误是因为我的汇编逻辑没有考虑 for 循环的 j < i 部分。我在正确的轨道上吗?
有两个问题:
当你递增 i 时,你忘记将 j 设置回 2。L3 应该向上移动 1 行。
ble 在 MIPS 中小于或等于,因此您的代码实际上是在检查 j <= i,而不是 j < i 。这会导致您的代码在 i = j 时检查 i % j,余数始终为 0 并且将注册为非素数。将 'ble' 更改为 'blt' 应该可以解决此问题。 i < n 检查也是如此。
还有一些额外的建设性批评:您设置 p=1 然后立即检查 p = 1。
li $t3, 1 # p = 1
beq $t3, 1, L4 # if p=1 break to next i
你可以去除 p 的冗余,将 p 完全删除,并将这两行替换为 L4 的无条件分支
b L4
Mips 打印两个输入数字之间的所有质数的程序,修改它以将下限设置为 1。
.text
.globl main
main:
# put mssge 1
li $v0, 4
la $a0, msg1
syscall
# take n1
li $v0, 5
syscall
move $t1, $v0
# put mssge 2
li $v0, 4
la $a0, msg2
syscall
# take n2
li $v0, 5
syscall
move $t2, $v0
# if n1 == n2
bne $t1, $t2, continue1
li $v0, 4
la $a0, msg4
syscall
j exit
continue1:
blt $t1,$t2, continue2
li $v0, 4
la $a0, msg3
syscall
move $t4, $t1
move $t1, $t2
move $t2, $t4
continue2:
bgt $zero,$t1, negRange
j continue3
negRange:
li $v0, 4
la $a0, msg5
syscall
j exit
continue3:
addi $t1, $t1, 1
# n and n+1 handle
beq $t1, $t2, noRange
j loop
noRange:
li $v0, 4
la $a0, msg4
syscall
j exit
# for loop for printing primes
loop:
# put num in $a0
#checkPrime called with jal
move $a0, $t1
jal checkPrime
#if $v0 is yes print else dont
move $t8, $v0
beq $t8, $zero, continue
li $v0, 1
move $a0, $t1
syscall
li $v0, 4
la $a0, endline
syscall
continue:
#update n1
addi $t1, $t1, 1
#loop till _i < n2
beq $t1, $t2, end_loop
j loop
end_loop:
exit:
li $v0, 10
syscall
# function for checking a number prime
# a0 gets number, v0 gets the return yes/no
# without stack
checkPrime:
li $t0, 2
# loop
li $t6, 1
beq $a0, $t6, not_prime
loopCheck:
rem $t3, $a0, $t0
beq $t3, $zero, not_prime
addi $t0, $t0, 1
beq $t0, $a0, end_loop_yes
j loopCheck
# put yes/no in $v0
not_prime:
li $v0, 0
jr $ra
end_loop_yes:
li $v0, 1
jr $ra
.data
msg1: .asciiz "Enter first number: "
msg2: .asciiz "Enter second number: "
msg3: .asciiz "Second number is less than First, exchanging and finding\n"
msg4: .asciiz "no number in between the range!\n"
msg5: .asciiz "negative range!\n"
endline: .asciiz "\n"
下面贴出了我的 MIPS 代码。 java 我基于的代码是...
Java代码...
for (int i=2;i<n;i++){
p = 0;
for (int j=2;j<i;j++){
if (i % j == 0)
p = 1;
}
if (p = 0) System.out.println(i);
}
我添加了行 "beq $t3, 1, L4" 以在 p 设置为 1 时跳至 L4 以节省时间。但是当我添加这行代码时,程序没有任何输出。在我添加这一行之前,它会打印 2~n 中的所有整数。
MIPS 代码...
# The number is read through the keyboard
.text
.globl main
main:
# Display message to user for a number
li $v0, 4
la $a0, prompt1
syscall
# read keyboard into $v0 (number x is upper bound number to find primes)
li $v0, 5
syscall
# move the number from $v0 to $t0
move $t0, $v0 # $t0 = n
# store 2 in $t1 and $t2
li $t1, 2 # i
li $t2, 2 # j
L3: # for (int i=2; i<n; i++)
# store 0 in $t3
li $t3, 0 # p = 0;
L2: # for (int j=2; j<i; j++)
# do div of two numbers
div $t2, $t1
# store the remainder in $t4
mfhi $t4
# branch if remainder is not 0 to L1
bne $t4, 0, L1 # if (i % j == 0)
# set $t3 as 1
li $t3, 1 # p = 1
# if p=1 break to next i
beq $t3, 1, L4
L1: # if (i % j == 0)
# add 1 to t2
addi $t2, $t2, 1 # j++
# repeat code while j < i
ble $t2, $t1, L2
# print integer function call 1
# put the answer into $a0
li $v0, 1
move $a0, $t1
syscall # System.out.println(i)
#print comma
li $v0, 4
la $a0, comma
syscall
L4:
# add 1 to t1
addi $t1, $t1, 1 # i++
# repeat code while i < n
ble $t1, $t0, L3 # for (int i=2; i<n; i++)
.data
prompt1:
.asciiz "Enter a number "
comma:
.asciiz ","
我认为发生错误是因为我的汇编逻辑没有考虑 for 循环的 j < i 部分。我在正确的轨道上吗?
有两个问题:
当你递增 i 时,你忘记将 j 设置回 2。L3 应该向上移动 1 行。
ble 在 MIPS 中小于或等于,因此您的代码实际上是在检查 j <= i,而不是 j < i 。这会导致您的代码在 i = j 时检查 i % j,余数始终为 0 并且将注册为非素数。将 'ble' 更改为 'blt' 应该可以解决此问题。 i < n 检查也是如此。
还有一些额外的建设性批评:您设置 p=1 然后立即检查 p = 1。
li $t3, 1 # p = 1
beq $t3, 1, L4 # if p=1 break to next i
你可以去除 p 的冗余,将 p 完全删除,并将这两行替换为 L4 的无条件分支
b L4
Mips 打印两个输入数字之间的所有质数的程序,修改它以将下限设置为 1。
.text
.globl main
main:
# put mssge 1
li $v0, 4
la $a0, msg1
syscall
# take n1
li $v0, 5
syscall
move $t1, $v0
# put mssge 2
li $v0, 4
la $a0, msg2
syscall
# take n2
li $v0, 5
syscall
move $t2, $v0
# if n1 == n2
bne $t1, $t2, continue1
li $v0, 4
la $a0, msg4
syscall
j exit
continue1:
blt $t1,$t2, continue2
li $v0, 4
la $a0, msg3
syscall
move $t4, $t1
move $t1, $t2
move $t2, $t4
continue2:
bgt $zero,$t1, negRange
j continue3
negRange:
li $v0, 4
la $a0, msg5
syscall
j exit
continue3:
addi $t1, $t1, 1
# n and n+1 handle
beq $t1, $t2, noRange
j loop
noRange:
li $v0, 4
la $a0, msg4
syscall
j exit
# for loop for printing primes
loop:
# put num in $a0
#checkPrime called with jal
move $a0, $t1
jal checkPrime
#if $v0 is yes print else dont
move $t8, $v0
beq $t8, $zero, continue
li $v0, 1
move $a0, $t1
syscall
li $v0, 4
la $a0, endline
syscall
continue:
#update n1
addi $t1, $t1, 1
#loop till _i < n2
beq $t1, $t2, end_loop
j loop
end_loop:
exit:
li $v0, 10
syscall
# function for checking a number prime
# a0 gets number, v0 gets the return yes/no
# without stack
checkPrime:
li $t0, 2
# loop
li $t6, 1
beq $a0, $t6, not_prime
loopCheck:
rem $t3, $a0, $t0
beq $t3, $zero, not_prime
addi $t0, $t0, 1
beq $t0, $a0, end_loop_yes
j loopCheck
# put yes/no in $v0
not_prime:
li $v0, 0
jr $ra
end_loop_yes:
li $v0, 1
jr $ra
.data
msg1: .asciiz "Enter first number: "
msg2: .asciiz "Enter second number: "
msg3: .asciiz "Second number is less than First, exchanging and finding\n"
msg4: .asciiz "no number in between the range!\n"
msg5: .asciiz "negative range!\n"
endline: .asciiz "\n"