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

MIPS程序运行时地址异常问题求助

Fixing the Runtime Exception in Your MIPS String Traversal Code

Hey there, let's break down why you're hitting that "Bad address" exception and fix it step by step:

Core Issue: Insufficient Stack Allocation

The biggest problem is in your loop_over_strings function—you only allocate 4 bytes of stack space with addi $sp, $sp, -4, but then try to store three different registers ($ra at 0($sp), $a0 at 4($sp), $a1 at 8($sp)). Accessing 4($sp) and 8($sp) is out of bounds for the 4-byte stack you reserved, which corrupts the stack structure and leads to invalid memory accesses when you try to load values back later.

Other Problems to Fix

  • Invalid String Syntax: Your .asciiz line uses HTML-escaped quotes (") instead of regular double quotes ("). QtSpim won't parse this correctly, so your string address will be wrong.
  • Missing ascii Function: You're jumping to ascii with jalr $a1, but there's no implementation for this function in your code. Without it, the jump will land at an invalid address and trigger another exception.
  • Redundant .text Section: You have two .text declarations, which is unnecessary and can cause confusion for the assembler.

Fixed Code

Here's the corrected version that should run without exceptions in QtSpim:

.data
STR_str: .asciiz "Cow, Bird, Beer"  # Fixed quote syntax
.text

# String traversal function with proper stack handling
.globl loop_over_strings
loop_over_strings:
    addi $sp, $sp, -12  # Allocate 12 bytes for 3 registers ($ra, $a0, $a1)
    sw $ra, 0($sp)
    sw $a1, 8($sp)      # Now safely within allocated stack space

loop:
    sw $a0, 4($sp)
    lb $t0, 0($a0)      # Load current character
    beqz $t0, end_loop  # Exit if we hit the null terminator

    jalr $a1            # Call the ascii function

    lw $a0, 4($sp)      # Restore $a0
    lw $a1, 8($sp)      # Restore $a1
    addi $a0, $a0, 1    # Move to next character
    j loop

end_loop:
    lw $ra, 0($sp)      # Restore return address
    addi $sp, $sp, 12   # Deallocate stack space
    jr $ra

# Main function
.globl main
main:
    addi $sp, $sp, -4
    sw $ra, 0($sp)

    la $a0, STR_str     # Load string address into $a0
    la $a1, ascii       # Load ascii function address into $a1
    jal loop_over_strings

    lw $ra, 0($sp)
    addi $sp, $sp, 4
    jr $ra

# Example implementation of the ascii function
# This prints each character from the string
ascii:
    li $v0, 11          # Syscall code for printing a character
    move $a0, $t0       # Pass the current character to the syscall
    syscall
    jr $ra

Key Takeaways

  • Always calculate exactly how much stack space you need: each register takes 4 bytes, so multiply the number of registers you're saving by 4.
  • Match stack allocation and deallocation: if you subtract 12 from $sp at the start, add 12 back before returning.
  • Make sure all functions you reference (like ascii) are implemented—undefined functions lead to invalid jumps.

You can use QtSpim's step-through debugging to watch the $sp register and confirm that all stack accesses are within the allocated space now.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:22:35