MIPS迷宫游戏按键无限移动问题调试及jr $ra实现需求
问题分析
你的问题核心是按键输入未处理释放状态:检测到WASD按下后,代码持续执行移动逻辑,未等待按键松开,导致角色无限移动直至模拟器崩溃。同时需要规范使用jr $ra实现子程序返回逻辑。
解决方案步骤
1. 新增按键释放检测逻辑
在执行完一次移动后,必须等待键盘MMIO寄存器回到无按键状态,才能进入下一次输入检测,避免重复触发移动。
键盘MMIO关键地址:
- 按键状态寄存器:
0xFFFF0000(bit 0为1表示有按键输入) - 按键数据寄存器:
0xFFFF0004(存储按下的ASCII码)
2. 用jal+jr $ra实现子程序调用
将移动逻辑封装为独立子程序,通过jal调用,子程序末尾用jr $ra返回主循环,符合MIPS子程序调用规范。
修改后的示例代码
.data # 角色坐标存储 playerX: .word 10 playerY: .word 10 # 键盘MMIO地址定义 KEYBOARD_STATUS: .word 0xFFFF0000 KEYBOARD_DATA: .word 0xFFFF0004 .text .globl main main: j gameUpdateLoop # 游戏主循环:等待输入、处理移动 gameUpdateLoop: # 等待按键按下 lw $t0, KEYBOARD_STATUS lw $t0, 0($t0) andi $t0, $t0, 1 beq $t0, $zero, gameUpdateLoop # 读取按键值 lw $t1, KEYBOARD_DATA lw $a0, 0($t1) # 分支调用对应移动子程序 li $t2, 'w' beq $a0, $t2, moveUp li $t2, 'a' beq $a0, $t2, moveLeft li $t2, 's' beq $a0, $t2, moveDown li $t2, 'd' beq $a0, $t2, moveRight # 等待按键释放(核心:防止重复触发) waitRelease: lw $t0, KEYBOARD_STATUS lw $t0, 0($t0) andi $t0, $t0, 1 bne $t0, $zero, waitRelease j gameUpdateLoop # 向上移动子程序 moveUp: lw $t0, playerY addi $t0, $t0, -1 sw $t0, playerY jr $ra # 向左移动子程序 moveLeft: lw $t0, playerX addi $t0, $t0, -1 sw $t0, playerX jr $ra # 向下移动子程序 moveDown: lw $t0, playerY addi $t0, $t0, 1 sw $t0, playerY jr $ra # 向右移动子程序 moveRight: lw $t0, playerX addi $t0, $t0, 1 sw $t0, playerX jr $ra
关键修改说明
- 按键释放等待:
waitRelease循环确保只有当按键松开后,才会回到主循环等待下一次输入,彻底解决一次按键触发无限移动的问题。 - 子程序调用规范:用
jal调用移动子程序,jr $ra返回调用点,替代直接j跳转,让代码结构更清晰,符合MIPS架构的子程序设计逻辑。
内容的提问来源于stack exchange,提问作者John Legaspi
相关产品推荐
相关产品推荐

