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

MIPS栈式链接子例程:$a0寄存器冲突引发QTSpim内存错误排查

问题描述

需编写采用栈式链接的MIPS子例程,实现提示用户输入字符串的功能:

  • 通过$a0传入输入缓冲区地址
  • 通过$a1传入缓冲区大小
  • 通过$a2传入提示信息地址

用户遇到的问题:$a0寄存器需同时用作系统调用8(读字符串)的缓冲区地址参数,以及系统调用4(打印字符串)的提示信息地址参数。尝试用move指令将$a0暂存到$s0,打印后恢复$a0,但在QTSpim中出现内存越界错误,相关代码如下:

.text
    .globl main
    
main:   la  $a0, str1           # prompting for two different strings
    li  $a1, 100
    la  $a2, prmpt1
    jal prompt
    nop
    la  $a0, str2
    li  $a1, 100
    la  $a2, prmpt2
    jal prompt
    nop

    
    li  $v0, 10
    syscall
    
prompt: 
    
    move    $s0, $a0    # save passed $a0
    
    li  $v0, 4      # print prompt
    move    $a0, $a2
    syscall
    move    $a0, $s0
    li  $v0, 8      # read input
    syscall
    jr  $ra
    nop



    .data
    
str1:   .space 120
str2:   .space 120

prmpt1: .asciiz "enter the first string : \n"
prmpt2: .asciiz "enter the second string : \n"
问题分析与解决

错误原因

MIPS的s寄存器(如$s0)属于被调用者保存寄存器,子例程若要修改这类寄存器,必须先将原值保存到栈中,使用完毕后恢复。直接修改$s0会破坏主程序中该寄存器的原有数据,进而引发内存访问异常。同时,题目要求的栈式链接也要求子例程正确维护栈帧,保存关键寄存器。

修正后的代码

.text
    .globl main
    
main:   
    la  $a0, str1           # 提示输入第一个字符串
    li  $a1, 100
    la  $a2, prmpt1
    jal prompt
    nop
    
    la  $a0, str2           # 提示输入第二个字符串
    li  $a1, 100
    la  $a2, prmpt2
    jal prompt
    nop

    li  $v0, 10
    syscall
    
prompt: 
    # 构建栈帧:分配空间保存$ra和$a0
    addi    $sp, $sp, -8    
    sw      $ra, 4($sp)     # 保存返回地址
    sw      $a0, 0($sp)     # 保存输入缓冲区地址到栈
    
    li  $v0, 4      # 打印提示信息
    move    $a0, $a2
    syscall
    
    lw      $a0, 0($sp)     # 从栈恢复输入缓冲区地址
    li  $v0, 8      # 读取用户输入
    syscall
    
    lw      $ra, 4($sp)     # 恢复返回地址
    addi    $sp, $sp, 8     # 销毁栈帧
    jr  $ra
    nop

    .data
    
str1:   .space 120
str2:   .space 120

prmpt1: .asciiz "enter the first string : \n"
prmpt2: .asciiz "enter the second string : \n"

关键说明

  1. 栈帧维护:子例程prompt先扩展栈空间,保存$ra(返回地址)和$a0(缓冲区地址),避免寄存器值被意外覆盖。
  2. 寄存器安全:改用栈暂存$a0,不再直接修改s寄存器,符合MIPS寄存器使用规范。
  3. 栈式链接实现:通过栈保存和恢复关键寄存器,保证主程序与子例程的寄存器状态互不干扰,满足题目要求的栈式链接逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:20:22