简体   繁体   中英

Recursive Pascal's triangle (Combination func) Assembly

I am trying to write a recursive combination function in assembly ( Yasm (similar to nsam)). I cannot use loops, multiplication or division.

I certain I am on the right track but am having issues once I hit the second inner function call. Can anyone help me and tell me where I am going wrong?

Edit: This is my updated code which returns a result but is not always correct. I think I must have a small bit of logic incorrect.

    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

This is a javascript implementation I have been using as a reference

function(n,k) {
    if ( k==0 || k==n ) {
        return 1
    } else {
        return C(n-1,k-1) + C(n-1,k)
    }
}
  1. The C(n-1,k) invocation is incorrect, because both rax and rbx have already been decremented and the recursive invocation destroys their value anyway. The simple fix is to reload the arguments from the stack.
  2. Similarly, the recursive invocation will use rdx for its own temporary, thereby overwriting the caller's copy. Solution: you should allocate a local variable on the stack, and use that as temporary storage.
  3. You are not restoring the stack pointer. At endfunc you should insert a mov esp, ebp .
  4. You are not following the usual calling convention. This is not a problem if you agree with the caller, but might still be a good idea to do so. You can get a quick overview at wikipedia .

PS: The usual advice applies: learn to use a debugger so you can fix your own mistakes.

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