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

MIPS汇编二叉树DFS/BFS代码无输出及PC错误调试求助

MIPS二叉树DFS/BFS及格式转换代码调试:PC值无效错误

我正在做一个项目,需要为两种不同格式的二叉树实现深度优先搜索(DFS)、广度优先搜索(BFS)算法,以及两种格式之间的转换程序。但代码运行时没有任何输出,MARS模拟器提示invalid program counter value: 0x00000000,执行因错误终止。请帮忙调试代码。

项目要求

  • 深度优先搜索(DFS):在二叉树中搜索指定值,返回元素所在层级,未找到则返回-1。
  • 广度优先搜索(BFS):在二叉树中搜索指定值,返回元素所在层级,未找到则返回-1。
  • 转换程序:
    • 从表示格式1转换为表示格式2
    • 从表示格式2转换为表示格式1
  • BFS实现:对两种格式的二叉树都能执行BFS

相关代码

.data
arraylist_data: .space 400
arraylist_size: .word 0
tree_rep1: .word 4, 9, 10, 10, 15, 2, 3
tree_rep2: .space 28
search_value: .word 10
queue_data: .space 100
queue_front: .word 0
queue_rear: .word -1
queue_size: .word 0
result_msg: .asciiz "Value found at level: "
not_found_msg: .asciiz "Value not found.\n"
dfs1_msg: .asciiz "DFS (Rep 1): "
dfs2_msg: .asciiz "DFS (Rep 2): "
bfs1_msg: .asciiz "BFS (Rep 1): "
bfs2_msg: .asciiz "BFS (Rep 2): "


.text
.globl main

# ArrayList Operations
create_arraylist:
    sw $zero, arraylist_size
    jr $ra

append_arraylist:
    lw $t0, arraylist_size
    sll $t1, $t0, 2
    la $t2, arraylist_data
    addu $t2, $t2, $t1
    sw $a0, 0($t2)
    addi $t0, $t0, 1
    sw $t0, arraylist_size
    jr $ra

get_arraylist_size:
    lw $v0, arraylist_size
    jr $ra

# Queue Operations
create_queue:
    li $t0, 0
    sw $t0, queue_front
    li $t0, -1
    sw $t0, queue_rear
    sw $zero, queue_size
    jr $ra

enqueue:
    lw $t0, queue_size
    li $t1, 100
    beq $t0, $t1, enqueue_full
    lw $t0, queue_rear
    addiu $t0, $t0, 1
    li $t1, 100
    rem $t0, $t0, $t1
    sw $t0, queue_rear
    la $t1, queue_data
    sll $t2, $t0, 2
    addu $t1, $t1, $t2
    sw $a0, 0($t1)
    lw $t0, queue_size
    addiu $t0, $t0, 1
    sw $t0, queue_size
    jr $ra

enqueue_full:
    jr $ra

dequeue:
    lw $t0, queue_size
    beqz $t0, dequeue_empty
    la $t0, queue_data
    lw $t1, queue_front
    sll $t2, $t1, 2
    addu $t0, $t0, $t2
    lw $v0, 0($t0)
    addiu $t1, $t1, 1
    li $t2, 100
    rem $t1, $t1, $t2
    sw $t1, queue_front
    lw $t0, queue_size
    addiu $t0, $t0, -1
    sw $t0, queue_size
    jr $ra

dequeue_empty:
    jr $ra

is_queue_empty:
    lw $t0, queue_size
    beqz $t0, is_empty
    li $v0, 0
    jr $ra

is_empty:
    li $v0, 1
    jr $ra

# Conversion Procedures
convert_rep1_to_rep2:
    addi $sp, $sp, -12
    sw $ra, 8($sp)
    sw $s0, 4($sp)
    sw $s1, 0($sp)
    jal create_arraylist
    move $s0, $a0
    li $a0, 0
    move $s1, $a1
    jal convert_helper_1_to_2
    la $t0, arraylist_data
    move $t1, $s1
    lw $t2, arraylist_size
    li $t3, 0
copy_loop:
    beq $t3, $t2, copy_done
    sll $t4, $t3, 2
    addu $t5, $t0, $t4
    lw $t6, 0($t5)
    sw $t6, 0($t1)
    addi $t1, $t1, 4
    addi $t3, $t3, 1
    j copy_loop
copy_done:
    lw $s1, 0($sp)
    lw $s0, 4($sp)
    lw $ra, 8($sp)
    addi $sp, $sp, 12
    move $v0, $s1
    jr $ra

convert_helper_1_to_2:
    blt $a0, 0, return_helper_1_to_2
    sll $t0, $a0, 2
    addu $t0, $s0, $t0
    lw $t1, 0($t0)
    move $a0, $t1
    jal append_arraylist
    sll $t3, $a0, 1
    addi $t3, $t3, 1
    addi $t4, $t3, 1
    lw $t6, arraylist_size
    blt $t3, $t6, process_left
    j check_right
process_left:
    move $a0, $t3
    jal convert_helper_1_to_2
check_right:
    lw $t6, arraylist_size
    blt $t4, $t6, process_right
    j return_helper_1_to_2
process_right:
    move $a0, $t4
    jal convert_helper_1_to_2
return_helper_1_to_2:
    jr $ra

convert_rep2_to_rep1:
    addi $sp, $sp, -16
    sw $ra, 12($sp)
    sw $s0, 8($sp)
    sw $s1, 4($sp)
    sw $s2, 0($sp)
    move $s0, $a2
    move $s1, $a0
    move $s2, $a1
    li $a0, 0
    li $a1, 0
    jal convert_helper_2_to_1
    lw $s2, 0($sp)
    lw $s1, 4($sp)
    lw $s0, 8($sp)
    lw $ra, 12($sp)
    addi $sp, $sp, 16
    move $v0, $s2
    jr $ra

convert_helper_2_to_1:
    blt $a0, $s0, valid_index
    j return_helper_2_to_1
valid_index:
    blt $a0, 0, return_helper_2_to_1
    sll $t0, $a0, 2
    addu $t0, $s1, $t0
    sll $t1, $a1, 2
    addu $t1, $s2, $t1
    lw $t2, 0($t0)
    sw $t2, 0($t1)
    addi $a0, $a0, 1
    addi $a1, $a1, 1
    jal convert_helper_2_to_1
    addi $a0, $a0, 1
    sll $t3, $a1, 1
    addi $a1, $t3, 1
    jal convert_helper_2_to_1
return_helper_2_to_1:
    jr $ra

# Depth-First Search
dfs_recursive:
    blt $a1, 0, dfs_not_found
    sll $t0, $a1, 2
    addu $t0, $a0, $t0
    lw $t1, 0($t0)
    bne $t1, $a2, check_left
    move $v0, $a3
    jr $ra
check_left:
    addi $t3, $a1, 1
    move $a1, $t3
    addi $a3, $a3, 1
    jal dfs_recursive
    move $t4, $v0
    bne $t4, -1, return_dfs
    addi $t5, $a1, 1
    sll $t5, $t5, 1
    addi $t5, $t5, 1
    move $a1, $t5
    jal dfs_recursive
    move $t6, $v0
    move $v0, $t6
    jr $ra
dfs_not_found:
    li $v0, -1
    jr $ra
return_dfs:
    move $v0, $t4
    jr $ra

# Breadth-First Search
bfs:
    addi $sp, $sp, -16
    sw $ra, 12($sp)
    sw $s0, 8($sp)
    sw $s1, 4($sp)
    sw $s2, 0($sp)
    la $s0, queue_data
    move $s1, $a0
    move $s2, $a2
    jal create_queue
    lw $t0, 0($s1)
    move $a0, $t0
    jal enqueue
bfs_loop:
    jal is_queue_empty
    bnez $v0, bfs_not_found
    jal dequeue
    move $t1, $v0
    lw $t2, 0($s1)
    beq $t1, $t2, bfs_found
    addi $a0, $a0, 1
    sll $t3, $a0, 2
    addu $t4, $s1, $t3
    lw $t5, 0($t4)
    move $a0, $t5
    jal enqueue
    j bfs_loop
bfs_found:
    lw $s2, 0($sp)
    lw $s1, 4($sp)
    lw $s0, 8($sp)
    lw $ra, 12($sp)
    addi $sp, $sp, 16
    jr $ra
bfs_not_found:
    lw $s2, 0($sp)
    lw $s1, 4($sp)
    lw $s0, 8($sp)
    lw $ra, 12($sp)
    addi $sp, $sp, 16
    li $v0, -1
    jr $ra

# Main Program
main:
    la $a0, tree_rep1
    li $a1, 7
    lw $a2, search_value
    li $a3, 0
    jal dfs_recursive
    move $t0, $v0
    la $a0, dfs1_msg
    li $v0, 4
    syscall
    move $a0, $t0
    li $v0, 1
    syscall
    la $a0, not_found_msg
    li $v0, 4
    syscall
    la $a0, tree_rep2
    li $a1, 7
    lw $a2, search_value
    li $a3, 0
    jal dfs_recursive
    move $t0, $v0
    la $a0, dfs2_msg
    li $v0, 4
    syscall
    move $a0, $t0
    li $v0, 1
    syscall
    la $a0, not_found_msg
    li $v0, 4
    syscall
    la $a0, tree_rep1
    lw $a2, search_value
    jal bfs
    move $t1, $v0
    la $a0, bfs1_msg
    li $v0, 4
    syscall
    move $a0, $t1
    li $v0, 1
    syscall
    la $a0, not_found_msg
    li $v0, 4
    syscall
    la $a0, tree_rep2
    lw $a2, search_value
    jal bfs
    move $t1, $v0
    la $a0, bfs2_msg
    li $v0, 4
    syscall
    move $a0, $t1
    li $v0, 1
    syscall
    la $a0, not_found_msg
    li $v0, 4
    syscall
    li $v0, 10
    syscall

MARS模拟器错误信息

汇编:操作成功完成。
错误:无效的程序计数器值:0x00000000
步骤:执行因错误终止。

核心错误修复方案

1. 格式转换函数寄存器使用错误

convert_rep1_to_rep2中错误地将$a1赋值给s1,实际应该传入tree_rep2的地址,且递归逻辑中索引计算错误。修复后代码:

convert_rep1_to_rep2:
    addi $sp, $sp, -12
    sw $ra, 8($sp)
    sw $s0, 4($sp)
    sw $s1, 0($sp)
    jal create_arraylist
    move $s0, $a0        # tree_rep1的地址
    la $s1, tree_rep2    # 目标地址tree_rep2
    li $a0, 0
    jal convert_helper_1_to_2
    la $t0, arraylist_data
    move $t1, $s1
    lw $t2, arraylist_size
    li $t3, 0
copy_loop:
    beq $t3, $t2, copy_done
    sll $t4, $t3, 2
    addu $t5, $t0, $t4
    lw $t6, 0($t5)
    sw $t6, 0($t1)
    addi $t1, $t1, 4
    addi $t3, $t3, 1
    j copy_loop
copy_done:
    lw $s1, 0($sp)
    lw $s0, 4($sp)
    lw $ra, 8($sp)
    addi $sp, $sp, 12
    move $v0, $s1
    jr $ra

convert_helper_1_to_2:
    blt $a0, 0, return_helper_1_to_2
    # 计算当前节点在tree_rep1中的地址
    sll $t0, $a0, 2
    addu $t0, $s0, $t0
    lw $t1, 0($t0)
    # 将节点值加入arraylist
    move $a0, $t1
    jal append_arraylist
    # 计算左右子节点索引(原tree_rep1中的索引)
    sll $t3, $a0, 1
    addi $t3, $t3, 1
    addi $t4, $t3, 1
    # 检查索引是否在tree_rep1的范围内(大小7)
    li $t6,7
    blt $t3, $t6, process_left
    j check_right
process_left:
    move $a0, $t3
    jal convert_helper_1_to_2
check_right:
    blt $t4, $t6, process_right
    j return_helper_1_to_2
process_right:
    move $a0, $t4
    jal convert_helper_1_to_2
return_helper_1_to_2:
    jr $ra

2. DFS递归逻辑错误

原DFS中修改$a1后无法正确计算右子节点索引,需要保存原索引:

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 06:01:00