简体   繁体   中英

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:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM