如何在MIPS中打印6×6二维数组?解决地址未对齐运行时错误
6×6二维数组打印的MIPS汇编实现方案
错误原因解析
- 地址对齐错误:MIPS架构要求字(4字节)访问的地址必须是4的倍数,若你之前的代码计算偏移量时未保证这一点,就会触发
fetch address not aligned on word boundary错误。 - 无限循环:通常是循环终止条件设置错误,或计数器未正确更新导致循环无法退出。
完整可行代码
.data arr: .word 0:36 # 定义6×6的int数组,初始化36个0 newline: .asciiz "\n" # 换行符 space: .asciiz " " # 元素间分隔空格 .text main: # 初始化数组(若已有预设数据可跳过此段) li $t0, 0 # 行计数器i=0 init_row_loop: beq $t0, 6, init_done # i等于6时结束初始化 li $t1, 0 # 列计数器j=0 init_col_loop: beq $t1, 6, init_col_done # j等于6时结束当前行初始化 # 计算字节偏移量:(i*6 + j) * 4 mul $t2, $t0, 6 add $t2, $t2, $t1 sll $t2, $t2, 2 # 左移2位等价于乘以4,保证地址对齐 # 给arr[i][j]赋值为i*6+j(示例值,可自定义) add $t3, $t2, $zero sw $t3, arr($t2) addi $t1, $t1, 1 # j自增1 j init_col_loop init_col_done: addi $t0, $t0, 1 # i自增1 j init_row_loop init_done: # 打印数组 li $t0, 0 # 行计数器i=0 print_row_loop: beq $t0, 6, print_done # i等于6时结束打印 li $t1, 0 # 列计数器j=0 print_col_loop: beq $t1, 6, print_col_done # j等于6时换行 # 计算字节偏移量 mul $t2, $t0, 6 add $t2, $t2, $t1 sll $t2, $t2, 2 # 加载并打印数组元素 lw $a0, arr($t2) li $v0, 1 syscall # 打印元素间空格 la $a0, space li $v0, 4 syscall addi $t1, $t1, 1 # j自增1 j print_col_loop print_col_done: # 打印换行符 la $a0, newline li $v0, 4 syscall addi $t0, $t0, 1 # i自增1 j print_row_loop print_done: # 退出程序 li $v0, 10 syscall
关键细节说明
- 地址对齐保障:
- 用
.word定义数组,默认起始地址是4字节对齐的; - 通过
sll $t2, $t2, 2将索引转换为字节偏移量,确保最终访问的内存地址始终是4的倍数,彻底规避对齐错误。
- 用
- 循环逻辑严谨性:
- 每个嵌套循环都明确设置了终止条件(
beq指令判断计数器等于6),且每次循环都通过addi更新计数器,从根源避免无限循环。
- 每个嵌套循环都明确设置了终止条件(
- 与Java逻辑的对应:
- 对应Java的双层循环,MIPS用
$t0作为行计数器(对应Java的i),$t1作为列计数器(对应Java的j); - Java中
arr[i][j]的索引计算i*6 + j,在MIPS中通过乘法和加法实现,再转换为字节偏移量适配MIPS的字节寻址模式; - 打印操作通过MIPS系统调用实现:
li $v0,1打印整数,li $v0,4打印字符串(空格、换行)。
- 对应Java的双层循环,MIPS用
内容的提问来源于stack exchange,提问作者David Santos
相关产品推荐
相关产品推荐

