You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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_array and read_array sections, you incorrectly wrote text instead of .text and data instead 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-$a3 for 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 to main.
  • Your allocate_array logic 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-$a1 to pass parameters to functions, and $v0-$v1 to 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 $ra in main)—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 .text and .data directives 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 $ra in main since temporary registers ($t0-$t9) don't require preservation across function calls.
  • Allocate Logic: Updated allocate_array to use the input length to calculate memory size, which is the correct way to dynamically allocate an array.
  • Return Value Handling: create_array now properly passes the array base and length back to main via registers, ensuring values aren't corrupted.

内容的提问来源于stack exchange,提问作者AnonCham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 23:02:43