簡體   English   中英

為什么這個 Risc-V 二叉樹檢查器不起作用?

[英]Why is this Risc-V Binary tree checker not working?

我正在嘗試編寫一個 Risc-V 樹檢查器:每棵樹的節點都由三個單詞組成:

1) 0 或 1

2) 左節點地址

3) 右節點地址

我的程序應該探索樹並返回第一個節點以 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

嘗試在調試器中單步執行,以查看每條指令是否具有您想要的效果。

使您的初始測試用例盡可能小,因為調試遞歸函數可能會非常混亂。 因此,例如,僅使用一個節點嘗試一下; 然后只有兩個節點(例如,左邊的根節點;右邊的根節點)。

最終你會看到:

lw a0, 4(sp)    <------- the result of this load is discarded
lw a0, 8(a0)    

這里第一次加載沒有意義,因為它獲得的a0值(立即)被第二次加載覆蓋。


    bne a0, zero, scelta
    jal skip
scelta:
    ble a0,t0,skip_add
    mv a0, t0
skip_add:

不要使用jal進行簡單的分支,而是使用j 雖然在這里它沒有傷害,但它確實更新了ra ,在簡單的 if-then-else 的上下文中你不想要它。 如果您有一個葉子 function 不能將ra保存在堆棧中,那就太糟糕了。

由於這個序列有一個條件分支,它會在一個無條件分支周圍跳轉,因此可以將其簡化為消除無條件分支和一個 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM