为什么这段MIPS代码没有在控制台打印出结果?

问题描述 投票:0回答:1

我必须计算从 1 到 n 的总和并在控制台上打印出两个结果。 但是当我执行这段代码时,我看不到 sum 的结果 你能重写一下代码并解释一下这段代码有什么问题吗?

.data
    integer:    .asciiz "\nEnter a positive integer: 
    result_1:   .asciiz "(Iterative)Sum from 1 to n: "
    result_2:   .asciiz "\n(Recursive)Sum from 1 to n: "
    newline:    .asciiz "\n"

.text
    main:
    
        # Print the prompt and read a positive integer from the console
        li $v0, 4
        la $a0, integer
        syscall

        read_input:
            li $v0, 5
            syscall
            move $t0, $v0   # Store n in $t0

            # Calculate the sum iteratively
            li $t1, 0   # Initialize sum to 0
            li $t2, 1   # Initialize the counter to 1

            loop_iterative:
                add $t1, $t1, $t2   # Add counter to sum
                addi $t2, $t2, 1     # Increment the counter

                # Check if the counter is less than or equal to n
                ble $t2, $t0, loop_iterative
                
            # Call the recursive function to calculate the sum 
            move $a0, $t0
            jal calculate_sum
            
            move $t3, $v0  # Save the result from the recursive call

            # Print a newline
            li $v0, 4
            la $a0, newline
            syscall
                    
            # Print the result_1
            li $v0, 4
            la $a0, result_1
            syscall

            move $a0, $t1
            li $v0, 1
            syscall
            
            # Print the result_2
            li $v0, 4
            la $a0, result_2
            syscall

            move $a0, $t3  # Use the result from the recursive call
            li $v0, 1
            syscall

            # Print a newline
            li $v0, 4
            la $a0, newline
            syscall

            # Exit the program
            li $v0, 10
            syscall
            
    calculate_sum:
        # Recursive function to calculate the sum
        # Input: $a0 - n
        # Output: $v0 - sum
        
        # if n <= 1, return 1
        blez $a0, calculate_sum_base
        li $v0, 0
        
        # Save the original $a0
        move $t4, $a0

        # Recursive case: call calculate_sum with n - 1
        addi $t4, $t4, -1
        move $a0, $t4
        jal calculate_sum

        # Add n to the result from the recursive call
        add $v0, $v0, $t4

        # Restore the original $a0
        move $a0, $t4

        jr $ra

    calculate_sum_base:
        li $v0, 1
        jr $ra
loops recursion sum mips
1个回答
0
投票

此代码的主要错误是您没有考虑作为 MIPS 汇编语言一部分的调用者保存和调用者保存约定,因此,这是一个概念错误。

查看您的代码,您在递归函数上退出程序一次 jr $ra ,因为您没有将 $ra 保存到堆栈中。

总体而言,按照惯例,在进入之前必须保存所有t寄存器 任何函数和 s 寄存器都必须保存在函数内以便 不丢失任何数据。

了解有关此约定的更多信息,请参阅 什么是被调用者和调用者保存的寄存器?

这是一个简化且有效的代码解决方案,它现在尊重被调用者和调用者保存约定:

.data
    integer:    .asciiz "\nEnter a positive integer: "
    result_1:   .asciiz "(Iterative)Sum from 1 to n: "
    result_2:   .asciiz "\n(Recursive)Sum from 1 to n: "
    newline:    .asciiz "\n"

.text
    main:
        addi $sp, $sp, -4   # Allocate space on the stack for $ra
        sw $ra, 0($sp)      # Save $ra on the stack
        # Print the prompt and read a positive integer from the console
        li $v0, 4
        la $a0, integer
        syscall

        read_input:
            li $v0, 5
            syscall
            move $t0, $v0   # Store n in $t0

            # Calculate the sum iteratively
            li $t1, 0   # Initialize sum to 0
            li $t2, 1   # Initialize the counter to 1

            loop_iterative:
                add $t1, $t1, $t2   # Add counter to sum
                addi $t2, $t2, 1     # Increment the counter

                # Check if the counter is less than or equal to n
                ble $t2, $t0, loop_iterative
                
            # Call the recursive function to calculate the sum 
            move $a0, $t0
            jal calculate_sum
            
            move $t3, $v0  # Save the result from the recursive call

            # Print a newline
            li $v0, 4
            la $a0, newline
            syscall
                    
            # Print the result_1
            li $v0, 4
            la $a0, result_1
            syscall

            move $a0, $t1
            li $v0, 1
            syscall
            
            # Print the result_2
            li $v0, 4
            la $a0, result_2
            syscall

            move $a0, $t3  # Use the result from the recursive call
            li $v0, 1
            syscall

            # Print a newline
            li $v0, 4
            la $a0, newline
            syscall

            # Exit the program
            lw $ra, 0($sp)
            addi $sp, $sp, 4
            jr $ra
            
    calculate_sum:
        # Recursive function to calculate the sum
        # Input: $a0 - n
        # Output: $v0 - sum
        addi $sp, $sp, -8   # Allocate space on the stack for $ra
        sw $ra, 0($sp)      # Save $ra on the stack
        sw $s0, 4($sp)      # Save n on the stack

        # Check if n is less than or equal to 1
        ble $a0, 1, base_case

        # Calculate the sum recursively
        move $s0, $a0       # Save n in $s0
        addi $a0, $a0, -1   # Decrement n
        jal calculate_sum   # Call the recursive function
        move $a0, $s0       # Restore n from $s0
        add $v0, $v0, $a0   # Add n to the result from the recursive call

        j end

    base_case:
        li $v0, 1   # Return 1
        j end
    end:
        lw $ra, 0($sp)
        lw $s0, 4($sp)
        addi $sp, $sp, 8
        jr $ra
© www.soinside.com 2019 - 2024. All rights reserved.