MIPS程序执行sw指令报错求助:存储操作异常原因排查
问题分析与修复方案
你的代码存在多处错误,和MARS模拟器无关,具体问题及修复如下:
1. save未分配内存空间
.data段里的save:只是一个地址标签,没有预留可写入的内存空间。执行sw $a0, save时,模拟器会试图往未分配的内存地址写入数据,直接触发内存访问错误。
修复:给save分配足够的空间,若要存储字符串地址,可写:
save: .space 4
若要直接存储字符串内容,按需分配字节数(比如10字节):
save: .space 10
2. 字符串定义错误
你用.ascii "aaa/0aab/0aac/0"定义的字符串里,/0不是ASCII空字符(字符串终止符),而是普通的/和0字符。这会导致每个“子字符串”没有正确的终止标记,后续打印时会读取到多余内容。
修复:把/0改成\0,正确的连续字符串定义应为:
normal: .ascii "aaa\0aab\0aac\0"
3. 核心逻辑错误:混淆字符串地址与内容
你的目标是取出第二个字符串的起始地址并打印,但代码里的lw $a0, ($a1)是错误的——$a1已经是第二个字符串的起始地址(normal+4),lw是加载该地址处的4字节内容(也就是"aab\0"这四个字符),而非获取地址本身。
修复:如果要把第二个字符串的地址存到save,直接把$a1的值存进去:
sw $a1, save
如果只是要打印第二个字符串,甚至不需要save,直接用$a1作为打印参数即可。
修复后的完整代码
.data normal: .ascii "aaa\0aab\0aac\0" # 用\0作为字符串终止符 save: .space 4 # 分配4字节存字符串地址 .text main: la $a1, normal # 加载字符串起始地址 addi $a1, $a1, 4 # 跳过第一个字符串("aaa\0"共4字节) sw $a1, save # 将第二个字符串的地址存入save # 打印第二个字符串 li $v0, 4 la $a0, save # 加载save的地址 lw $a0, ($a0) # 从save中取出第二个字符串的地址 syscall # 或者直接打印,不需要save: # li $v0,4 # move $a0,$a1 # syscall li $v0, 10 syscall
额外说明
MARS模拟器的字符串打印syscall(编号4)要求$a0存放字符串的起始地址,而非字符串内容。如果你直接把字符串内容存在save里,需要确保内容末尾有\0,并且打印时把save的地址传给$a0;但更合理的方式是保存字符串的地址,因为原字符串已经在.data段存在,不需要复制内容。
内容的提问来源于stack exchange,提问作者David Herrezuelo Paredes
相关产品推荐
相关产品推荐

