提问人:Eric Mariasis 提问时间:11/17/2023 最后编辑:Peter CordesEric Mariasis 更新时间:11/17/2023 访问量:29
由于明显缺乏对寄存器 a4 和 a5 的支持,无法让 MIP 代码在 QTSpim 中专门工作
Having trouble getting MIPs code to work specifically in QTSpim due to apparent lack of support for registers a4 and a5
问:
我下面有一些MIP代码,这些代码是我根据下面进一步开发的一些C代码开发的。我所做工作的前提是计算输入矩阵的最长递增路径,但这似乎与我的问题没有太大关系。当我尝试在 QTSpim 中运行 MIPs 代码时,它在首次使用寄存器 a4 和 a5 时出错,这表明它可能不支持这些代码。我尝试使用一些建议的策略,例如使用堆栈和额外的临时寄存器,但我无法让它们工作。任何建议将不胜感激!如果可能的话,我想让它在 QTSpim 中工作。
MIPs 代码
.data
prompt_rows: .asciiz "Enter the number of rows: "
prompt_cols: .asciiz "Enter the number of columns: "
prompt_value: .asciiz "Enter value for row "
space: .asciiz " column "
newline: .asciiz "\n"
matrix_rows: .word 0
matrix_cols: .word 0
.text
.globl main
main:
# Read number of rows
li $v0, 4
la $a0, prompt_rows
syscall
li $v0, 5
syscall
sw $v0, matrix_rows
# Read number of columns
li $v0, 4
la $a0, prompt_cols
syscall
li $v0, 5
syscall
sw $v0, matrix_cols
# Load rows and cols into registers
lw $t0, matrix_rows # $t0 = number of rows
lw $t1, matrix_cols # $t1 = number of columns
# Calculate total number of elements (rows * cols) for main matrix
mul $t2, $t0, $t1 # $t2 = total elements
# Allocate memory for the main matrix
sll $t2, $t2, 2 # Multiply total elements by 4 (size of word)
li $v0, 9 # Syscall for memory allocation
move $a0, $t2
syscall
move $t3, $v0 # $t3 = base address of the main matrix
# Initialize counters for rows and columns
li $t4, 0 # Row counter
li $t5, 0 # Column counter
read_loop:
# Check if loop is done
bge $t4, $t0, end_read_loop
# Output prompt for value
li $v0, 4
la $a0, prompt_value
syscall
li $v0, 1
move $a0, $t4
syscall
li $v0, 4
la $a0, space
syscall
li $v0, 1
move $a0, $t5
syscall
li $v0, 4
la $a0, newline
syscall
# Read integer
li $v0, 5
syscall
# Store the value in the matrix
sw $v0, 0($t3)
# Print a tab character
li $v0, 11 # Print character syscall
li $a0, 9 # ASCII code for tab character
syscall
# Increment address, row, and column counters
addi $t3, $t3, 4
addi $t5, $t5, 1
# Check if it's the end of the row
beq $t5, $t1, print_tab_newline
j read_loop
print_tab_newline:
# Print a tab+newline
li $v0, 11 # Print character syscall
li $a0, 9 # ASCII code for tab character
syscall
li $v0, 11 # Print character syscall
li $a0, 10 # ASCII code for newline character
syscall
# Increment row counter and reset column counter
addi $t4, $t4, 1
li $t5, 0
j read_loop
end_read_loop:
# Reset $t3 to the start of the main matrix
sub $t3, $t3, $t2
# Auxiliary matrix creation and initialization starts here
# Reuse $t2 for the total number of elements in the auxiliary matrix
# Allocate memory for the auxiliary matrix
li $v0, 9 # Syscall for memory allocation
move $a0, $t2
syscall
move $t7, $v0 # $t7 = base address of the auxiliary matrix
# Initialize the auxiliary matrix to -1
li $t8, 0 # Counter for the number of initialized elements
li $t9, -1 # Value to initialize each element (-1)
initialize_aux_matrix:
bge $t8, $t2, end_initialize_aux # Check if all elements are initialized
sw $t9, 0($t7) # Store -1 in the current element
addi $t7, $t7, 4 # Move to the next element
addi $t8, $t8, 4 # Increment counter
j initialize_aux_matrix
end_initialize_aux:
# Setup for calling compute_LIP
li $a0, 0 # Initial row index
li $a1, 0 # Initial column index
move $a2, $t3 # Pass the base address of the main matrix
move $a3, $t7 # Pass the base address of the auxiliary matrix
move $a4, $t0 # Pass the number of rows
move $a5, $t1 # Pass the number of columns
# Call compute_LIP
jal compute_LIP
# Handle the returned value here
move $s1, $v0 # Store the length of the longest increasing path
# Print the length as a single integer value
li $v0, 1
move $a0, $s1
syscall
# Exit
li $v0, 10
syscall
compute_LIP:
# Load value from auxiliary matrix at current index
lw $t7, 0($a3)
bgez $t7, return_from_compute_LIP # If value is non-negative, use it
# Initialize result
li $t9, 0
# Check for bottom-right corner
addi $t0, $a0, 1 # x + 1
addi $t1, $a1, 1 # y + 1
beq $a0, $a4, is_bottom_right # if x == m - 1
beq $a1, $a5, is_bottom_right # if y == n - 1
# Recursive call for right neighbor
recursive_right:
blt $t0, $a4, check_right # if x + 1 < m
j recursive_down
check_right:
# Load current and right element, compare
# Call compute_LIP if right element is greater
# Update $t9 with max($t9, 1 + returned value)
# Recursive call for down neighbor
recursive_down:
blt $t1, $a5, check_down # if y + 1 < n
j update_aux_matrix
check_down:
# Load current and down element, compare
# Call compute_LIP if down element is greater
# Update $t9 with max($t9, 1 + returned value)
# Store the result in the auxiliary matrix
update_aux_matrix:
sw $t9, 0($a3)
j return_from_compute_LIP
is_bottom_right:
li $t9, 1
sw $t9, 0($a3)
return_from_compute_LIP:
move $v0, $t9
jr $ra
check_neighbor:
# Assuming $t0 is row index for neighbor, $t1 is column index for neighbor
# and $t10 is the value of the current element
# Calculate address of neighbor element in the main matrix
sll $t2, $t0, 2 # Row index * 4 (word size)
mul $t2, $t2, $a5 # Multiply by number of columns
add $t2, $t2, $t1 # Add column index
sll $t2, $t2, 2 # Multiply by word size
add $t2, $a2, $t2 # Add base address of main matrix
lw $t3, 0($t2) # Load neighbor element
# Check if neighbor is greater than current element
ble $t3, $t10, return_from_neighbor # If not greater, return
# If neighbor is greater, make a recursive call
move $a0, $t0 # Set new row index for recursive call
move $a1, $t1 # Set new column index for recursive call
jal compute_LIP # Recursive call to compute_LIP
# Compare and update the result
addi $t4, $v0, 1 # Add 1 to the returned path length
bgt $t4, $t9, update_max_path # If new path is longer, update max length
return_from_neighbor:
jr $ra # Return from subroutine
update_max_path:
move $t9, $t4 # Update maximum path length
j return_from_neighbor # Return to the caller
aux_not_computed:
# Otherwise, compute the value using the LIP algorithm
# Initialize result to 0
li $t9, 0
# Get the current element from the main matrix
mul $t8, $a0, $a5
add $t8, $t8, $a1
sll $t8, $t8, 2
add $t8, $a2, $t8
lw $t10, 0($t8)
# Check if we are at the bottom-right corner
beq $a0, $a4, check_right
beq $a1, $a5, check_right
# Check the right cell
addi $t1, $a1, 1
mul $t2, $a0, $a5
add $t2, $t2, $t1
sll $t2, $t2, 2
add $t2, $a2, $t2
lw $t11, 0($t2)
bge $t11, $t10, check_right
# Recursive call for right cell
addi $a1, $a1, 1
jal compute_LIP
addi $t12, $v0, 1
b check_down
check_right:
move $t12, $t9
check_down:
# Check the down cell
addi $t1, $a0, 1
mul $t2, $t1, $a5
add $t2, $t2, $a1
sll $t2, $t2, 2
add $t2, $a2, $t2
lw $t11, 0($t2)
bge $t11, $t10, store_result
# Recursive call for down cell
addi $a0, $a0, 1
jal compute_LIP
add $t3, $v0, 1
b store_result
store_result:
# Store the maximum of right and down paths
max $t9, $t12, $t3
# Store the result in the auxiliary matrix
sw $t9, 0($a3)
# Return the result
move $v0, $t9
jr $ra
C 代码
#include <stdio.h>
#include <stdlib.h>
int compute_LIP(int x, int y, int *main_matrix, int *aux_matrix, int rows, int cols);
int main() {
int rows, cols;
printf("Enter the number of rows: ");
scanf("%d", &rows);
printf("Enter the number of columns: ");
scanf("%d", &cols);
// Allocate memory for the main matrix
int *matrix = (int *)malloc(rows * cols * sizeof(int));
if (!matrix) {
fprintf(stderr, "Memory allocation failed.\n");
return 1;
}
// Read matrix elements
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("Enter value for row %d column %d: ", i, j);
scanf("%d", &matrix[i * cols + j]);
}
}
// Allocate memory for the auxiliary matrix
int *aux_matrix = (int *)malloc(rows * cols * sizeof(int));
if (!aux_matrix) {
fprintf(stderr, "Memory allocation failed.\n");
free(matrix);
return 1;
}
// Initialize auxiliary matrix to -1
for (int i = 0; i < rows * cols; i++) {
aux_matrix[i] = -1;
}
// Call compute_LIP and get the result
int lip_length = compute_LIP(0, 0, matrix, aux_matrix, rows, cols);
// Print the result
printf("Length of the longest increasing path: %d\n", lip_length);
// Cleanup
free(matrix);
free(aux_matrix);
return 0;
}
int compute_LIP(int x, int y, int *main_matrix, int *aux_matrix, int rows, int cols) {
// Check if the auxiliary matrix already has a computed value
if (aux_matrix[x * cols + y] != -1) {
return aux_matrix[x * cols + y];
}
int max_path = 1; // Minimum path length is 1 (the current cell)
int current_value = main_matrix[x * cols + y];
// Check right neighbor
if (y + 1 < cols && main_matrix[x * cols + (y + 1)] > current_value) {
int right_path = 1 + compute_LIP(x, y + 1, main_matrix, aux_matrix, rows, cols);
if (right_path > max_path) {
max_path = right_path;
}
}
// Check down neighbor
if (x + 1 < rows && main_matrix[(x + 1) * cols + y] > current_value) {
int down_path = 1 + compute_LIP(x + 1, y, main_matrix, aux_matrix, rows, cols);
if (down_path > max_path) {
max_path = down_path;
}
}
// Store the computed value in the auxiliary matrix and return it
aux_matrix[x * cols + y] = max_path;
return max_path;
}
如上所述,我尝试了一些策略来保留功能,同时消除寄存器 a4 和 a5 的使用,但我无法让它们工作。
答: 暂无答案
评论
$t0-$t9
$t6
$t10
$s0-$s7
$ra
$fp
$v0
$v1