[英]Why is this Risc-V Binary tree checker not working?
I'm trying to write a Risc-V tree checker: every tree's node is composed of three words:我正在尝试编写一个 Risc-V 树检查器:每棵树的节点都由三个单词组成:
1)Either 0 or 1 1) 0 或 1
2)Left node's address 2) 左节点地址
3)Right node's address 3) 右节点地址
My program should explore the tree and return how deep into the tree is the first node with a 1 as the first word, here's the code:我的程序应该探索树并返回第一个节点以 1 作为第一个单词的深度,这是代码:
.data
tree: .word n01
n01: .word 0, n02, n03
n02: .word 0, n04, n05
n03: .word 0, n06, n07
n04: .word 0, 0, 0
n05: .word 0, 0, 0
n06: .word 1, 0, 0
n07: .word 0, 0, 0
.text
lw a0, tree
jal altezza
addi a0, a0, -1
li a7, 1
ecall
li a7, 10
ecall
altezza:
bne a0, zero, altezza_ric
jalr zero, ra, 0
altezza_ric:
addi sp, sp, -12
lw t1, 0(a0)
sw ra, 0(sp)
bne t1, zero, skip_numb
sw a0, 4(sp)
lw a0, 4(a0)
jal altezza
sw a0, 8(sp)
lw a0, 4(sp)
lw a0, 8(a0)
jal altezza
lw t0, 8(sp)
bne a0, zero, scelta
mv a0, t0
bne a0, zero, scelta
jal skip
scelta:
ble a0,t0,skip_add
mv a0, t0
skip_add:
addi a0, a0, 1 #ad a0 inremento 1
skip: lw ra, 0(sp)
addi sp, sp, 12
jalr zero, ra, 0
skip_numb:
add a0, zero, zero
jal skip_add
Try single stepping in the debugger to see if each instruction has the effect you want.尝试在调试器中单步执行,以查看每条指令是否具有您想要的效果。
Make your initial test cases as small as possible, because debugging recursive functions can be very confusing.使您的初始测试用例尽可能小,因为调试递归函数可能会非常混乱。 So try it with just one node, for example;
因此,例如,仅使用一个节点尝试一下; then just two nodes (eg a root node with a left; a root node with a right).
然后只有两个节点(例如,左边的根节点;右边的根节点)。
Eventually you'll see this:最终你会看到:
lw a0, 4(sp) <------- the result of this load is discarded
lw a0, 8(a0)
Here the first load is meaningless, because the a0
value it obtains is (immediately) overwritten by the second load.这里第一次加载没有意义,因为它获得的
a0
值(立即)被第二次加载覆盖。
bne a0, zero, scelta
jal skip
scelta:
ble a0,t0,skip_add
mv a0, t0
skip_add:
Don't use jal
for simple branching, use j
instead.不要使用
jal
进行简单的分支,而是使用j
。 While here it doesn't hurt, it does update ra
, which you don't want in the context of a simple if-then-else.虽然在这里它没有伤害,但它确实更新了
ra
,在简单的 if-then-else 的上下文中你不想要它。 If you had a leaf function that doesn't save ra
in the stack, this would be bad.如果您有一个叶子 function 不能将
ra
保存在堆栈中,那就太糟糕了。
As this sequence has a conditional branch that jumps around an unconditional branch, this can be simplified to eliminate the unconditional branch and a label ( scelta:
) as follows:由于这个序列有一个条件分支,它会在一个无条件分支周围跳转,因此可以将其简化为消除无条件分支和一个 label (
scelta:
),如下所示:
beq a0, zero, skip <--- reverse the condition and branch to the other target
<--- eliminate/omit the unconditional branch and other label
ble a0,t0,skip_add
mv a0, t0
skip_add:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.