为何无法从栈中获取$a0的原始存储值?仅能获取修改后的值
MIPS汇编栈存取问题解答
你的问题核心是:栈里存的是$a0寄存器中的字符串地址,不是字符串内容本身。
问题细节分析
- 执行
sw $a0, 0($sp)时,只是把$a0里的内存地址(指向"hello"的起始位置)保存到栈中,并没有把"hello"这几个字符复制到栈里。 - 后续代码中,
add $t0, $a0, $a2让$t0指向$a0地址偏移$a2的位置,接着通过sb $t2, ($t0)直接修改了$a0指向的内存区域内容,把"hello"改成了"heabc"。 - 最后
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
相关产品推荐
相关产品推荐

