            segment .data
            struc   node
    n_value resq    1
    n_next  resq    1
    n_prev  resq    1
            align   8
            endstruc
            segment .text
            global  main, newlist, insert, print
            extern  malloc, printf, scanf

    ;       list = newlist();
    newlist:
            push    rbp
            mov     rbp, rsp
            sub     rsp, 32
            mov     ecx, node_size
            call    malloc
            mov     [rax+n_next], rax  ; list points to itself
            mov     [rax+n_prev], rax  ; empty list
            leave
            ret

    ;       insert ( list, k );
    insert:
    .list   equ     local1
    .k      equ     local2
            push    rbp
            mov     rbp, rsp
            frame   2. 2. 1
            sub     rsp, frame_size
            mov     [rbp+.list], rcx  ; save list pointer
            mov     [rbp+.k], rdx     ; and k on stack
            mov     ecx, node_size
            call    malloc            ; rax will be node pointer
            mov     r8, [rbp+.list]   ; get list pointer
            mov     r9, [r8+n_next]   ; get head's next
            mov     [rax+n_next], r9  ; set new node's next
            mov     [rax+n_prev], r8  ; set new node's prev
            mov     [r8+n_next], rax  ; set head's next
            mov     [r9+n_prev], rax  ; set new node's next's prev
            mov     r9, [rbp+.k]      ; get k
            mov     [rax+n_value], r9 ; save k in node
            leave
            ret

    ;       print ( list );
    print:
            segment .data
    .print_fmt:
            db      "%ld ",0
    .newline:
            db      0x0a,0
            segment .text
    .list   equ     local1
    .rbx    equ     local2
            push    rbp
            mov     rbp, rsp
            frame   1, 0, 2
            sub     rsp, frame_size
            mov     [rbp+.rbx], rbx
            mov     [rbp+.list], rcx
            mov     rbx, [rcx+n_next]
            cmp     rbx, [rbp+.list]
            je      .done
    .more   lea     rcx, [.print_fmt]
            mov     rdx, [rbx+n_value]
            call    printf
            mov     rbx, [rbx+n_next]
            cmp     rbx, [rbp+.list]
            jne     .more
    .done   lea     rcx, [.newline]
            call    printf
            mov     rbx, [rbp+.rbx]
            leave
            ret

    main:
    .list   equ     local1
    .k      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    newlist
            mov     [rbp+.list], rax
    .more   lea     rcx, [.scanf_fmt]
            lea     rdx, [rbp+.k]
            call    scanf
            cmp     rax, 1
            jne     .done
            mov     rcx, [rbp+.list]
            mov     rdx, [rbp+.k]
            call    insert
            mov     rcx, [rbp+.list]
            call    print
            jmp     .more
    .done   leave
            ret