## Program u main funkciji poziva funkciju sum koja 
## vraca sumu niza elemenata, a zatim ispisuje sumu
## na izlaz. Funkcija sum izracunava sumu rekurzivno.

.intel_syntax noprefix

# Pocetak sekcije sa inicijalizovanim podacima.
.data

# Podatak koji predstavlja format string funkcije printf().
fmt: .asciz "%d\n"

# Podatak koji predstavlja niz celih brojeva.
array: .int 12,4,54,1,2,4,6,7

# Podatak koji predstavlja dimenziju gornjeg niza
n: .int 8

# Pocetak sekcije sa kodom. 
.text

# Definicija globalnih simbola
.global main

########################
## int main()
########################

main:
    # Prolog funkcije.
    enter   0,0

    # Pozivanje funkcije sum(array,n);
    lea     rdi, array
    mov     esi, n
    call    sum

    # Pozivanje funkcije printf("%d\n",rax)
    lea     rdi, fmt
    mov     esi, eax
    call    printf

    # Epilog funkcije
    xor     rax,rax
    leave
    ret

############################
## int sum(int *a, int n) ##
## 
## rdi -- int *a
## esi -- int n
############################

sum:
    # Prolog funkcije
    enter   0,0

    # U rcx smestamo vrednost dimenzije niza
    mov     ecx, esi

    # Ako je ova dimenzija 0, idemo na izlaz iz rekurzije.
    # jecxz komanda proverava da li registar ecx jednak nuli
    # ova komanda postoji zato sto registar ecx cesto koristimo za brojace u petlji
    # takodje, cesto zelimo da proverimo da li je brojac dosao do nule
    jecxz   rec_exit

    # Umesto prethodne komande (jecxz rec_exit) mogli smo 
    # iskoristiti sledece komande:
    # cmp   ecx 0
    # je    rec_exit

    # Pomeramo rdi da pokazuje na adresu narednog elementa
    add     rdi, 4

    # Smanjujemo broj elemenata niza za jedan
    dec     esi

    # Sada rekurzivnim pozivom racunamo sumu elemenata
    # ostatka niza.
    call    sum

    # Pomeramo rdi da pokazuje nazad na trenutni element
    sub     rdi, 4

    # Na povratnu vrednost (koja je u eax-u) dodajemo
    # vrednost trenutnog elementa (prvog u nizu)
    # Tako dobijamo sumu svih elemenata niza. 
    add     eax, [rdi]

    jmp     done

    # U slucaju niza duzine 0, vracamo 0. Ovo je izlaz
    # iz rekurzije.
rec_exit:
    xor     rax,rax

done:
    # Epilog funkcije
    leave
    ret
