MIPS汇编代码,用于查找输入数字下方的所有素数

时间:2016-10-25 18:20:07

标签: assembly mips primes

下面我发布了我的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);
}

我添加了行&#34; beq $ t3,1,L4&#34;当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 ","

我认为发生错误是因为我的汇编逻辑没有考虑j&lt;我是for循环的一部分。我是在正确的轨道上吗?

2 个答案:

答案 0 :(得分:2)

有两个问题:

  1. 当你增加i时,你忘记将j设置为2. L3应该向上移动1行。

  2. MIPS中的
  3. 小于或等于,因此您的代码实际上是在检查 j&lt; = i ,而不是 j&lt; I 即可。这会导致您的代码在i = j 时检查 i%j,它总是有一个余数0并且将注册为非素数。将'ble'更改为'blt'应该可以解决此问题。同样适用于i&lt;检查。

  4. 还有一些额外的建设性批评:你设置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
    

答案 1 :(得分:0)

打印两个输入数字之间的所有素数的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"