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

MIPS环境下打印8x8二维棋盘数组问题求助

MIPS战舰棋盘程序调试问题解决

问题概述

正在开发一款类似战舰的游戏程序,使用8x8二维数组作为棋盘,初始时棋盘中心(第4行对应位置)有一个标记为V的舰船。调试时发现代码仅执行一次内层循环后就跳过,只打印大量换行;尝试在外部循环开始时重置寄存器$t3为0后情况更糟,要么无有效输出,要么仅输出换行。

期望输出格式:

ABCDEFG
1
2
3
4   V
5
6
7

问题代码

.data
board:  .ascii " ABCDEFG"
    .ascii "1        "
    .ascii "2        "
    .ascii "3        "
    .ascii "4    V   "
    .ascii "5        "
    .ascii "6        "
    .ascii "7        "
    

.text

main:
    
#Build the board
    li  $t0, 8
    li $t1, 8
    la $t6, board
    li $t2, 0   # set i to 0 for outerloop
    li $t3, 0   #set j = 0
    jal, boardOuterLoop #jump to building board loops
    
    
    boardOuterLoop:
    bge $t1, $t2, endOuterLoop # basically...for (int i = 0; i < row; i++) 
    
    li $t3, 0   #reset j = 0 for next ineration through innerloop
    
    boardInnerLoop:
    bge $t3, $t0, endInnerLoop  #  basically...for(int j = 0; j<col; j++)
    #find address of each index
    mul $t4, $t2, $t1       # col* i
        add $t4, $t4, $t3       # (col* i) + j
        sll $t4, $t4, 2         # 2^2 * (width * i + j)
        add $t4, $t6, $t4   #bass add + $t4
    
        addi $t3, $t3, 1    # j++
    
    #print index
    li $v0, 11
    sw  $a0, 0($t4)
        syscall 
        
    b boardInnerLoop    #branch back to beginning of inner loop
    
    endInnerLoop:
    li $v0, 4
        la $a0, newline
        syscall
        
        addi $t2, $t2, 1    #i++
        
    b boardOuterLoop
    
    endOuterLoop:
    jr $ra

错误点分析与修复方案

1. 外层循环分支条件颠倒

原外层循环判断bge $t1, $t2, endOuterLoop逻辑完全错误:要实现for(i=0; i<row; i++),应该是当i >= row时才跳转到结束,正确写法是bge $t2, $t1, endOuterLoop,否则会直接跳过整个外层循环。

2. 地址计算冗余且错误

board是用.ascii定义的单字节字符数组,每个元素占1字节,但代码里用了sll $t4, $t4, 2(乘以4),导致地址偏移过大,读取到无效内存数据。直接删除这行即可。

3. 打印逻辑完全搞反

使用syscall 11(打印单个字符)时,需要把目标字符加载到$a0,但原代码用sw $a0, 0($t4)把$a0的值存到内存,完全反向。应该改成lb $a0, 0($t4),从内存读取字符到$a0后再调用打印。

4. 缺失换行符定义

代码里调用la $a0, newline但未在.data段定义该标签,需要添加newline: .asciiz "\n",否则会访问无效地址。

5. 跳转指令语法错误

jal, boardOuterLoop中的逗号是多余的,MIPS指令里jal后直接跟标签,正确写法是jal boardOuterLoop。

修复后的完整代码

.data
board:  .ascii " ABCDEFG"
        .ascii "1        "
        .ascii "2        "
        .ascii "3        "
        .ascii "4    V   "
        .ascii "5        "
        .ascii "6        "
        .ascii "7        "
newline: .asciiz "\n"

.text

main:
    # 初始化参数
    li  $t0, 8          # 列数
    li  $t1, 8          # 行数
    la  $t6, board      # 棋盘基地址
    li  $t2, 0          # 外层循环变量i=0
    jal boardOuterLoop  # 跳转到外层循环

boardOuterLoop:
    bge $t2, $t1, endOuterLoop  # 当i >= 8时结束外层循环
    li  $t3, 0          # 重置内层循环变量j=0

boardInnerLoop:
    bge $t3, $t0, endInnerLoop  # 当j >=8时结束内层循环
    # 计算当前字符地址
    mul $t4, $t2, $t1   # i * 列数
    add $t4, $t4, $t3   # i*col + j
    add $t4, $t6, $t4   # 基地址 + 偏移量
    # 打印单个字符
    li  $v0, 11
    lb  $a0, 0($t4)     # 从内存读取字符到$a0
    syscall
    addi $t3, $t3, 1    # j++
    b boardInnerLoop    # 回到内层循环开头

endInnerLoop:
    # 打印换行
    li  $v0, 4
    la  $a0, newline
    syscall
    addi $t2, $t2, 1    # i++
    b boardOuterLoop    # 回到外层循环开头

endOuterLoop:
    jr $ra

内容的提问来源于stack exchange,提问作者Sara Malos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 19:31:00