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

MIPS汇编beq条件失效:无法识别空白字符致循环无法终止

解析PPM文件头部时循环无法终止的问题

我正在解析从文件读取的缓冲区,拆分不同部分以获取变量值。相关代码片段如下:

# corrected
read_width: 
    li $v0, 14              # 读取系统调用码
    move $a0, $s0           # 文件描述符
    move $a1, $t1           # 缓冲区地址
    li $a2, 1               # 最大读取长度
    syscall

    lb $t2, ($t1)                       # 加载读取到的字符
    move $t7, $t2
    addi $t1, $t1, 1
    beq $t2, whitespace, print          # 检查是否为空白字符
    beq $t2, 10, print          # 检查是否为换行符
    j read_width

在QtSPIM中运行该代码时,循环始终无法终止,会持续读取并存储整个文件,而不是在第一行的第一个'64'后停止。运行输出如下:

[10010000] 230a3350 74654a20 2034360a 320a3436 P 3 . # J e
t . 6 4 6 4 . 2 [10010010] 310a3535 310a3636 310a3638
310a3138 5 5 . 1 6 6 . 1 8 6 . 1 8 1 . 1 [10010020] 310a3537
310a3738 310a3039 310a3937 7 5 . 1 8 7 . 1 9 0 . 1 7 9 . 1
[10010030] 310a3239 310a3239 310a3837 310a3539 9 2 . 1 9 2 .
1 7 8 . 1 9 5 . 1 [10010040] 310a3339 310a3737 310a3639
310a3339 9 3 . 1 7 7 . 1 9 6 . 1 9 3 . 1 [10010050] 310a3837
310a3839 310a3439 310a3937 7 8 . 1 9 8 . 1 9 4 . 1 7 9 . 1
[10010060] 310a3939 310a3539 320a3038 310a3030 9 9 . 1 9 5 .
1 8 0 . 2 0 0 . 1 [10010070] 310a3639 320a3238 Link(j福-bAJ中庭 "而今左右,更快

310a3639 9 6 . 1 8 2 . 2 0 1 . 1 9 6 . 1 [10010080] 320a3438
310a3230 310a3839 320a3338 8 4 . 2 0 2 . 1 9 8 . 1 8 3 . 2
[10010090] 310a3230 310a3839 310a3937 310a3939 0 2 . 1 9 8 .
1 7 9 . 1 9 9 . 1 [100100a0] 310a3739 320a3138 310a3130
310a3839 9 7 . 1 8 1 . 2 0 1 . 1 9 8 . 1

附上完整运行代码,恳请提供技术帮助:

.data
    header_buffer:  .space 256     # 存储头部的缓冲区
    width:          .word 0
    height:         .word 0 
    max_val:        .word 0
    filename: .asciiz "input.ppm" # 修改为你的输入文件名

.text
    .globl main
    
main:
        # 打开文件
        li $v0, 13              # 打开系统调用码
        la $a0, filename        # 将文件名加载到$a0
        li $a1, 0               # 只读模式
        syscall
        move $s0, $v0           # 将文件描述符保存到$s0

        # 读取文件的前4行头部
        la $t1, header_buffer   # 加载头部缓冲区地址
    
# 读取文件第一行 - 应为P2/P3
read_head:
        li $v0, 14              # 读取系统调用码
        move $a0, $s0           # 文件描述符
        move $a1, $t1           # 缓冲区地址
        li $a2, 1               # 最大读取长度
        syscall
    
    # 检查是否到达第一行末尾
    lb $t4, 0($t1)              # 加载读取到的字符
    addi $t1, $t1, 1
        beq $t4, 10, read_comment   # 换行符,到达行尾
    j read_head
    
# 读取文件第二行,检查是否为注释
read_comment:
    li $v0, 14              # 读取系统调用码
        move $a0, $s0           # 文件描述符
        move $a1, $t1           # 缓冲区地址
        li $a2, 1               # 最大读取长度
        syscall
    
    # 检查是否为注释行
    lb $t4, 0($t1)                      # 加载读取到的字符
    addi $t1, $t1, 1
        bne $t4, 35, read_width     # 如果第一个字符不是#,跳转到读取宽度的逻辑
    
read_comment_loop:
    li $v0, 14              # 读取系统调用码
        move $a0, $s0           # 文件描述符
        move $a1, $t1           # 缓冲区地址
        li $a2, 1               # 最大读取长度
        syscall
    
    # 检查是否到达注释行末尾
    lb $t4, 0($t1)                      # 加载读取到的字符
    addi $t1, $t1, 1
        beq $t4, 10, read_width     # 换行符,到达行尾
    j read_comment_loop
    
read_width: 
 SPDX         matching quot.风度[tea   Far(o同《陈com
    li $v0, 14              # 读取系统调用码
    move $a0, $s0           # 文件描述符
    move $a1, $t1           # 缓冲区地址
    li $a2, 1               # 最大读取长度
    syscall

    lb $t2, ($t1)                       # 加载读取到的字符
    move $t7, $t2
    addi $t1, $t1, 1
    beq $t2, whitespace, print          # 检查是否为空白字符
    beq $t2, 10, print          # 检查是否为换行符
    j read_width
    
exit:
    # 关闭文件
    li $v0, 16           # 关闭系统调用码
    move $a0, $s0        # 文件描述符
    syscall

    # 退出程序
    li $v0, 10           # 退出系统调用码
    syscall

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 02:29:51