簡體   English   中英

遞歸Pascal三角形(組合函數)裝配

[英]Recursive Pascal's triangle (Combination func) Assembly

我正在嘗試在匯編中編寫一個遞歸組合函數Yasm (類似於nsam))。 我不能使用循環,乘法或除法。

我確定我的工作是正確的,但是一旦我執行第二個內部函數調用,就會遇到問題。 誰能幫助我,告訴我我要去哪里了?

編輯:這是我更新的代碼,它返回結果,但並不總是正確的。 我認為我必須有一點邏輯錯誤。

    mov     rax, [n]
    push    rax
    mov     rax, [k]
    push    rax
    call    func    
    ...     ...     program continues from here

 func:                      
    push    rbp 
    mov     rbp, rsp

    push    rdi
    push    rsi

    cmp     rsi, 0
    je      stopcond
    cmp     rdi, rsi
    jne     contin

stopcond:
    mov     rax, 1
    jmp     endfunc
contin:
    ;C(n-1,k-1)
    mov     rax, [rsp]  ; This is k
    dec     rax
    mov     rdx, rax
    mov     rax, [rsp+8]  ; This is n
    dec     rax
    mov     rsi, rdx
    mov     rdi, rax
    call    func

    mov     rbx, rax
    mov     rax, [rsp+8]  ; This is n
    dec     rax
    mov     rdx, rax
    mov     rax, [rsp]  ; This is k
    mov     rsi, rax
    mov     rdi, rdx
    call    func

    add     rax, rbx

endfunc:
    add     rsp, 16
    pop     rbp
    ret

這是我一直用作參考的javascript實現

function(n,k) {
    if ( k==0 || k==n ) {
        return 1
    } else {
        return C(n-1,k-1) + C(n-1,k)
    }
}
  1. C(n-1,k)調用是不正確的,因為raxrbx都已減小,並且遞歸調用無論如何都會破壞它們的值。 簡單的解決方法是從堆棧中重新加載參數。
  2. 同樣,遞歸調用將把rdx用作其自己的臨時文件,從而覆蓋調用者的副本。 解決方案:您應該在堆棧上分配一個局部變量,並將其用作臨時存儲。
  3. 您沒有還原堆棧指針。 endfunc您應該插入mov esp, ebp
  4. 您沒有遵循通常的調用約定。 如果您同意呼叫者的意見,這不是問題,但這樣做仍然是一個好主意。 您可以在Wikipedia上獲得快速概述。

PS:通常的建議適用:學習使用調試器,以便您可以糾正自己的錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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