segment .data
        struc   node
n_value resq    1
n_left  resq    1
n_right resq    1
        align   8
        endstruc
        struc   tree
t_count resq    1
t_root  resq    1
        align   8
        endstruc

        segment .text
        global  main, new_tree, insert, print, rec_print, find
        extern  malloc, scanf, printf

new_tree:
        push    rbp
        mov     rbp, rsp
        frame   0, 0, 1
        sub     rsp, frame_size
        mov     rcx, tree_size
        call    malloc
        xor     edx, edx
        mov     [rax+t_root], rdx
        mov     [rax+t_count], rdx
        leave
        ret

;       insert ( t, n );
insert:
.n      equ     local1
.t      equ     local2
        push    rbp
        mov     rbp, rsp
        frame   2, 2, 2
        sub     rsp, frame_size
        mov     [rbp+.t], rcx
        mov     [rbp+.n], rdx
        call    find
        cmp     rax, 0
        jne     .done 
        mov     rcx, node_size
        call    malloc
        mov     rdx, [rbp+.n]
        mov     [rax+n_value], rdx
        xor     r8d, r8d
        mov     [rax+n_left], r8
        mov     [rax+n_right], r8
        mov     r9, [rbp+.t]
        mov     rcx, [r9+t_count]
        cmp     rcx, 0
        jne     .findparent
        inc     qword [r9+t_count]
        mov     [r9+t_root], rax
        jmp     .done
.findparent:
        inc     qword [r9+t_count]
        mov     r9, [r9+t_root]
.repeatfind:
        cmp     rdx, [r9+n_value]
        jl      .goleft
        mov     r8, r9
        mov     r9, [r8+n_right]
        cmp     r9, 0
        jne     .repeatfind
        mov     [r8+n_right], rax
        jmp     .done
.goleft:
        mov     r8, r9
        mov     r9, [r8+n_left]
        cmp     r9, 0
        jne     .repeatfind
        mov     [r8+n_left], rax
.done   leave
        ret

;       p = find ( t, n );
;       p = 0 if not found
find:
        push    rbp
        mov     rbp, rsp
        frame   2, 0, 0
        sub     rsp, frame_size
        mov     rcx, [rcx+t_root]
        xor     eax, eax
.more   cmp     rcx, 0
        je      .done
        cmp     rdx, [rcx+n_value]
        jl      .goleft
        jg      .goright
        mov     rax, rcx
        jmp     .done
.goleft:
        mov     rcx, [rcx+n_left]
        jmp     .more
.goright:
        mov     rcx, [rcx+n_right]
        jmp     .more
.done   leave
        ret

rec_print:
.t      equ     local1
        push    rbp
        mov     rbp, rsp
        frame   1, 1, 2
        sub     rsp, frame_size
        cmp     rcx, 0
        je      .done
        mov     [rbp+.t], rcx
        mov     rcx, [rcx+n_left]
        call    rec_print
        mov     rcx, [rbp+.t]
        mov     rdx, [rcx+n_value]
        segment .data
.print  db      "%ld ",0
        segment .text
        lea     rcx, [.print]
        call    printf
        mov     rcx, [rbp+.t]
        mov     rcx, [rcx+n_right]
        call    rec_print
.done   leave
        ret

;       print(t);
print:
        push    rbp
        mov     rbp, rsp
        frame   1, 0, 1
        mov     rcx, [rcx+t_root]
        call    rec_print
        segment .data
.print  db      0x0a, 0
        segment .text
        lea     rcx, [.print]
        call    printf
        leave
        ret

main:
.k      equ     local1
.t      equ     local2
        segment .data
.scanf_fmt:
        db      "%ld",0
        segment .text
        push    rbp
        mov     rbp, rsp
        frame   2, 2, 2
        sub     rsp, frame_size
        call    new_tree
        mov     [rbp+.t], rax
.more   lea     rcx, [.scanf_fmt]
        lea     rdx, [rbp+.k]
        call    scanf
        cmp     rax, 1
        jne     .done
        mov     rcx, [rbp+.t]
        mov     rdx, [rbp+.k]
        call    insert
        mov     rcx, [rbp+.t]
        call    print
        jmp     .more
.done   leave
        ret