segment .text
        extern  printf, rand, srand, malloc, atol
        global  main, create, fill, min

;       array = create ( size );
create:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        imul    rcx, 4
        call    malloc
        leave
        ret

;       fill ( array, size );
fill:
.array  equ     local1
.size   equ     local2
.i      equ     local3
        push    rbp
        mov     rbp, rsp
        frame   2. 3, 1
        sub     rsp, frame_size
        mov     [rbp+.array], rcx
        mov     [rbp+.size], rdx
        xor     r9d, r9d
.more   mov     [rbp+.i], r9
        call    rand
        mov     r9, [rbp+.i]
        mov     rcx, [rbp+.array]
        mov     [rcx+r9*4], eax
        inc     r9
        cmp     r9, [rbp+.size]
        jl      .more
        leave
        ret

;       print ( array, size );
print:
.array  equ     local1
.size   equ     local2
.i      equ     local3
        push    rbp
        mov     rbp, rsp
        frame   2, 3, 2
        sub     rsp, frame_size
        mov     [rbp+.array], rcx
        mov     [rbp+.size], rdx
        xor     ebx, ebx
        mov     [rbp+.i], rbx
        segment .data
.format:
        db      "%10d",0x0a,0
        segment .text
.more   lea     rcx, [.format]
        mov     rdx, [rbp+.array]
        mov     rbx, [rbp+.i]
        mov     edx, [rdx+rbx*4]
        mov     [rbp+.i], rbx
        call    printf
        mov     rbx, [rbp+.i]
        inc     rbx
        mov     [rbp+.i], rbx
        cmp     rbx, [rbp+.size]
        jl      .more
        leave
        ret

;       x = min ( array, size );
min:
        mov     eax, [rcx]
        mov     edx, 1
.more   mov     r8d, [rcx+rdx*4]
        cmp     r8d, eax
        cmovl   eax, r8d
        inc     rdx
        cmp     rdx, rdx
        jl      .more
        ret

main:
.array  equ     local1
.size   equ     local2
        push    rbp
        mov     rbp, rsp
        frame   2, 2, 2
        sub     rsp, frame_size
        
;       set default size
        mov     eax, 10
        mov     [rsp+.size], rax

;       check for argv[1] providing a size
        cmp     ecx, 2
        jl      .nosize
        mov     rcx, [rdx+8]
        call    atol
        mov     [rsp+.size], rax
.nosize:

;       create the array
        mov     rcx, [rsp+.size]
        call    create
        mov     [rsp+.array], rax
        
        mov     rcx, 10321
        call    srand

;       fill the array with random numbers
        mov     rcx, [rsp+.array]
        mov     rdx, [rsp+.size]
        call    fill

;       if size <= 20 print the array
        mov     rdx, [rsp+.size]
        cmp     rdx, 20
        jg      .toobig
        mov     rcx, [rsp+.array]
        call    print
.toobig:

;       print the minimum
        segment .data
.format:
        db      "min: %ld",0xa,0
        segment .text
        mov     rcx, [rsp+.array]
        mov     rdx, [rsp+.size]
        call    min
        lea     rcx, [.format]
        mov     rdx, rax
        call    printf

        leave
        ret