【问题标题】:MIPS Assembly code to find all the prime numbers below an inputted numberMIPS 汇编代码,用于查找输入数字下方的所有素数
【发布时间】:2016-10-25 18:20:07
【问题描述】:

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

【问题讨论】:

    标签: assembly mips primes


    【解决方案1】:

    有两个问题:

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

    2. MIPS 中的 ble 小于或等于,因此您的代码实际上是检查 j ,而不是 j 。这会导致您的代码在 i = j 时检查 i % j,它的余数始终为 0,并且将注册为非素数。将 'ble' 更改为 'blt' 应该可以解决此问题。 i

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

    【讨论】:

    • 非常感谢。我将看看无条件分支。这是否意味着它无论如何都会跳?
    • @Joshua Lee。实际上有两种方法:无条件分支,即“b L4”和无条件跳转,即“J L4”。从编码的角度来看,它们是相同的,但有一些幕后的东西使它们不同。您可以在此处找到有关差异的更多信息:stackoverflow.com/questions/10981593/…
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2014-07-21
      • 2013-07-25
      • 2018-04-06
      • 2020-06-09
      • 1970-01-01
      • 1970-01-01
      • 2016-08-27
      • 2017-12-20
      • 2011-12-18
      相关资源
      最近更新 更多