MIPS汇编:内存映射I/O轮询方式下检测换行符终止输入问题
问题分析与修复方案
你的代码核心问题在于换行符的表示错误,以下是具体修复步骤及优化建议:
1. 换行符的错误表示
你写的beq $a0,'\\n',end是错误的:在MIPS汇编的字符常量中,'\\n'会被解析成两个字符(反斜杠\和字母n),而非换行符对应的ASCII值(十进制10,十六进制0xA)。
正确写法有两种:
- 直接使用ASCII数值:
beq $a0, 10, end - 直接使用字符常量:
beq $a0, '\n', end(汇编器会自动将'\n'转换为对应ASCII码10)
2. 逻辑顺序优化(可选)
当前代码会把换行符也存入数组,如果需求是输入换行符时终止,且不存储换行符,需要调整检测与存储的顺序:
# 读取字符后先检测换行符 lw $a0, 4($t0) # Get character from keyboard beq $a0, 10, end # 检测到换行符直接终止 # 再执行计数、回显、存储操作 addi $s1,$s1,1 li $v0,11 syscall sw $a0,($s2) addi $s2,$s2,4 bne $s1,$s0,wait_keyboard
修复后的完整代码
.data array: .word 0:10 .globl main .text main: la $s2,array li $t0, 0xffff0000 # Address of keyboard control register li $t1, 0 # Initialize wait_counter = 0 li $s0,10 li $s1,0 wait_keyboard: lw $t2, ($t0) # Read the keyboard control register andi $t2, $t2, 1 # Extract ready bit addiu $t1, $t1, 1 # wait_counter++ (counts iterations) beqz $t2, wait_keyboard # loop back while not ready lw $a0, 4($t0) # Get character from keyboard # 先检测换行符,避免存入数组 beq $a0, '\n', end addi $s1,$s1,1 li $v0,11 syscall sw $a0,($s2) addi $s2,$s2,4 bne $s1,$s0,wait_keyboard end: #End Program li $v0,10 syscall
额外说明
你使用内存映射I/O+轮询的键盘读取逻辑是正确的:轮询控制寄存器的就绪位(最低位),就绪后从控制寄存器+4的地址读取字符,这部分无需修改。
内容的提问来源于stack exchange,提问作者LichKing456
相关产品推荐
相关产品推荐

