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

为何无法从栈中获取$a0的原始存储值?仅能获取修改后的值

MIPS汇编栈存取问题解答

你的问题核心是:栈里存的是$a0寄存器中的字符串地址,不是字符串内容本身。

问题细节分析

  1. 执行sw $a0, 0($sp)时,只是把$a0里的内存地址(指向"hello"的起始位置)保存到栈中,并没有把"hello"这几个字符复制到栈里。
  2. 后续代码中,add $t0, $a0, $a2让$t0指向$a0地址偏移$a2的位置,接着通过sb $t2, ($t0)直接修改了$a0指向的内存区域内容,把"hello"改成了"heabc"。
  3. 最后lw $a0, 0($sp)取出的还是原来的地址,而这块地址对应的内存已经被修改,所以syscall输出的自然是修改后的"heabc",而不是原始的"hello"。

你的代码(标注关键问题点)

string_insert:

addi $sp, $sp, -200
sw $a0, 0($sp)  # 这里存的是$a0的地址,不是"hello"内容
#insertion point
add $t0, $a0, $a2  # $t0指向$a0地址的偏移位置,直接操作原字符串内存

lb $t2, ($a1)
loop:
  beq $t2, $zero, end # 若字符为null则退出循环
  sb $t2, ($t0)           # 直接修改$a0指向的内存内容
  addi $t0, $t0, 1        # 插入位置自增
  addi $a1, $a1, 1        # 移动到第二个字符串的下一个字符
  lb $t2, ($a1)           # 加载第二个字符串的下一个字符
  j loop

# 循环结束
end:
sb $zero, ($t0)
lw $a0, 0($sp)  # 取出的是原地址,内存已被修改
addi $sp, $sp, 200
li $v0, 4
move $a0, $a0
syscall
jr $ra

解决思路

如果要保留原始字符串"hello",需要把字符串的内容保存到栈中,而不是只存地址:

  • 先循环读取$a0指向的每个字符,依次存入栈的200字节空间(比如从1($sp)开始存,因为0($sp)已存地址)
  • 后续需要恢复原始内容时,再从栈循环读取字符,写回原地址或者另一个缓冲区
  • 或者在修改前,把原始字符串复制到一块新的内存区域,避免直接修改$a0指向的原内存

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:35:10