我必须计算从 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
此代码的主要错误是您没有考虑作为 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