            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
            mov     rdi, tree_size
            call    malloc
            xor     edi, edi
            mov     [rax+t_root], rdi
            mov     [rax+t_count], rdi
            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], rdi
            mov     [rbp+.n], rsi
            call    find
            cmp     rax, 0
            jne     .done
            mov     rdi, node_size
            call    malloc
            mov     rsi, [rbp+.n]
            mov     [rax+n_value], rsi
            xor     edi, edi
            mov     [rax+n_left], rdi
            mov     [rax+n_right], rdi
            mov     rdx, [rbp+.t]
            mov     rdi, [rdx+t_count]
            cmp     rdi, 0
            jne     .findparent
            inc     qword [rdx+t_count]
            mov     [rdx+t_root], rax
            jmp     .done
    .findparent:
            inc     qword [rdx+t_count]
            mov     rdx, [rdx+t_root]
    .repeatfind:
            cmp     rsi, [rdx+n_value]
            jl      .goleft
            mov     r8, rdx
            mov     rdx, [r8+n_right]
            cmp     rdx, 0
            jne     .repeatfind
            mov     [r8+n_right], rax
            jmp     .done
    .goleft:
            mov     r8, rdx
            mov     rdx, [r8+n_left]
            cmp     rdx, 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
            mov     rdi, [rdi+t_root]
            xor     eax, eax
    .more   cmp     rdi, 0
            je      .done
            cmp     rsi, [rdi+n_value]
            jl      .goleft
            jg      .goright
            mov     rax, rsi
            jmp     .done
    .goleft:
            mov     rdi, [rdi+n_left]
            jmp     .more
    .goright:
            mov     rdi, [rdi+n_right]
            jmp     .more
    .done   leave
            ret

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

    ;       print(t);
    print:
            push    rbp
            mov     rbp, rsp
            mov     rdi, [rdi+t_root]
            call    rec_print
            segment .data
    .print  db      0x0a, 0
            segment .text
            lea     rdi, [.print]
            xor     eax, eax
            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     rdi, [.scanf_fmt]
            lea     rsi, [rbp+.k]
            xor     eax, eax
            call    scanf
            cmp     rax, 1
            jne     .done
            mov     rdi, [rbp+.t]
            mov     rsi, [rbp+.k]
            call    insert
            mov     rdi, [rbp+.t]
            call    print
            jmp     .more
    .done   leave
            ret