MIPS汇编转写C字符串循环时报错Bad address in data/stack如何修复
问题根因
你遇到的Bad address报错核心原因是内存地址计算重复叠加了基地址,触发了非法内存访问:
- 你已经通过
la $s4, high_score加偏移计算的操作,把high_score.name[i]的完整有效地址存储到了$s4寄存器中 - 后续写内存时误用了
sb $s3, high_score($s4)的语法,相当于把high_score的基地址又额外叠加了一次到$s4上,最终得到的地址超出了合法数据段范围,触发访问异常
修复后的汇编代码
li $s2, 0 loop4: lb $s3, user_name($s2) # 读取user_name[i] beqz $s3, string_endwhile # 遇到字符串结束符跳出循环 la $s4, high_score # 加载high_score结构体基地址 addi $s4, $s4, 4 # 偏移4字节定位到name成员的首地址 add $s4, $s4, $s2 # 加上下标i的偏移得到当前目标字符的地址 sb $s3, 0($s4) # 写入字符到对应地址,无需再加high_score基地址 addi $s2, $s2, 1 j loop4 string_endwhile: la $s4, high_score addi $s4, $s4, 4 add $s4, $s4, $s2 sb $zero, 0($s4) # 写入字符串结束符
可选优化方案
可以把high_score.name的基地址计算放到循环外,避免每次循环重复执行地址加载指令,提升运行效率:
li $s2, 0 la $s4, high_score addi $s4, $s4, 4 # 循环外提前计算好name成员的首地址,无需循环内重复计算 loop4: lb $s3, user_name($s2) beqz $s3, string_endwhile add $t0, $s4, $s2 # 用临时寄存器计算当前字符地址,不破坏$s4存储的基地址 sb $s3, 0($t0) addi $s2, $s2, 1 j loop4 string_endwhile: add $t0, $s4, $s2 sb $zero, 0($t0)
内容的提问来源于stack exchange,提问作者Quoc Tuan
相关产品推荐
相关产品推荐

