MIPS程序报错Unknown Instruction Type:0及create_array函数返回参数异常排查求助
Fixing MIPS Assembly Stack Management and Instruction Errors in Array Handling Code
Let's break down the issues in your MIPS code and fix them step by step. You're dealing with two main problems: corrupted return values from create_array and an "Unknown Instruction Type" error, both stemming from stack mismanagement and syntax mistakes.
Key Issues in Your Code
1. Invalid Directive Spelling (Causing "Unknown Instruction Type: 0")
- In the
allocate_arrayandread_arraysections, you incorrectly wrotetextinstead of.textanddatainstead of.data. These are invalid assembly directives— the assembler can't recognize them, which triggers the unknown instruction error.
2. Broken Stack Frame Management & Parameter Passing
- You're using the stack to pass parameters, which is allowed but implemented incorrectly, leading to stack pointer misalignment and corrupted register values. MIPS convention typically uses
$a0-$a3for parameter passing, which simplifies this process. - The
$ra(return address) save/restore logic is messy: unnecessary stack operations and incorrect order of loading/storing values cause the program to lose track of where it should return, and corrupt the array base address/length you're trying to pass back tomain. - Your
allocate_arraylogic was backwards: it was receiving a base address instead of the array length, which is what you need to calculate the size of memory to allocate.
Step-by-Step Fixes
Fix Directive Spelling
First, correct all misspelled segment directives: replace text with .text and data with .data everywhere.
Adopt MIPS Standard Calling Convention
- Use
$a0-$a1to pass parameters to functions, and$v0-$v1to return values—this aligns with MIPS best practices and avoids stack-related bugs. - Only save registers that need to be preserved across function calls (like
$rainmain)—temporary registers ($t0-$t9) don't need saving unless you need their values after a function call.
Correct Array Allocation Logic
Modify allocate_array to accept the array length as input, calculate the required memory size (length × 4 bytes per word), and return the new allocated base address in $v0.
Fixed Full Code
.data array: .word 0 length: .word 0 prompt: .asciiz "Enter in a number between 5-12: " error: .asciiz "Invalid entry! Try Again!\n" read_values_prompt: .asciiz "Enter an integer: " .text main: addi $sp, $sp, -4 # Save return address to stack sw $ra, 0($sp) jal create_array # Call create_array: returns array base in $v0, length in $v1 sw $v0, array # Save array base to global variable sw $v1, length # Save length to global variable lw $ra, 0($sp) # Restore return address addi $sp, $sp, 4 li $v0, 10 # Exit program syscall syscall # create_array: Prompts for valid length, calls allocate_array and read_array # Returns: $v0 = array base address, $v1 = array length create_array: li $t8, 5 li $t9, 12 create_array_loop: # Prompt user for array length li $v0, 4 la $a0, prompt syscall # Read integer input li $v0, 5 syscall # Validate input (5-12 inclusive) blt $v0, $t8, error_line bgt $v0, $t9, error_line move $a0, $v0 # Pass length to allocate_array via $a0 jal allocate_array # Allocate memory: returns base address in $v0 move $t0, $v0 # Save array base to temporary register move $t1, $a0 # Save valid length to temporary register # Prepare parameters for read_array move $a0, $t0 # $a0 = array base address move $a1, $t1 # $a1 = array length jal read_array # Set return values for main move $v0, $t0 move $v1, $t1 jr $ra # Return to main function error_line: li $v0, 4 la $a0, error syscall j create_array_loop # allocate_array: Allocates memory for the array # Input: $a0 = array length # Returns: $v0 = allocated array base address allocate_array: sll $a0, $a0, 2 # Calculate total bytes: length * 4 bytes per word li $v0, 9 # Syscall for memory allocation (sbrk) syscall # $v0 holds the base address of allocated memory jr $ra # read_array: Reads user integers into the array # Input: $a0 = array base address, $a1 = array length # No return value read_array: move $t0, $a0 # $t0 = current array pointer move $t1, $a1 # $t1 = remaining elements to read read_array_loop: blez $t1, read_array_end # Exit loop if all elements are read # Prompt for integer input li $v0, 4 la $a0, read_values_prompt syscall # Read integer li $v0, 5 syscall sw $v0, 0($t0) # Store input value in the array addi $t0, $t0, 4 # Move pointer to next word addi $t1, $t1, -1 # Decrement remaining element count b read_array_loop read_array_end: jr $ra
Explanation of Fixes
- Directive Correction: Fixed misspelled
.textand.datadirectives to eliminate the unknown instruction error. - Calling Convention: Used MIPS standard registers for parameters (
$a0-$a1) and return values ($v0-$v1) to simplify code and avoid stack misalignment. - Stack Management: Only saved/restored
$rainmainsince temporary registers ($t0-$t9) don't require preservation across function calls. - Allocate Logic: Updated
allocate_arrayto use the input length to calculate memory size, which is the correct way to dynamically allocate an array. - Return Value Handling:
create_arraynow properly passes the array base and length back tomainvia registers, ensuring values aren't corrupted.
内容的提问来源于stack exchange,提问作者AnonCham
相关产品推荐
相关产品推荐

