I'm trying to write a Risc-V tree checker: every tree's node is composed of three words:
1)Either 0 or 1
2)Left node's address
3)Right node's address
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:
.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.
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. While here it doesn't hurt, it does update ra
, which you don't want in the context of a simple if-then-else. If you had a leaf function that doesn't save ra
in the stack, this would be bad.
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:
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:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.