## Program kreira child proces, a zatim stampa id-eve
## parent-a i child-a iz oba procesa. Ukoliko se child
## uspava na dve sekunde, moguce je da ce se parent
## zavrsiti pre child-a, pa ce parent child-a postati
## init.

## Novi sistemski pozivi:
## fork()    -- create a new process by duplicating the current process
## getpid()  -- get process ID of the currently running process
## getppid() -- get parent's process ID of the currently running process


.intel_syntax noprefix

.data 
ppmsg: .asciz "Parend id (from parent): %d\n"
pcmsg: .asciz "Parent id (from child): %d\n"
ccmsg: .asciz "Child id (from child): %d\n"
cpmsg: .asciz "Child id (from parent): %d\n"

.text

.global main

main:
    enter   0,0

                        ## Pozivamo fork() sistemski poziv
    call    fork

                        ## Poredimo povratnu vrednost fork-a sa 0. 
                        ## fork() vraca 0 u child-u, vrednost 
                        ## razlicitu od nule u parent-u. 
    cmp     eax, 0
    je      child

                        ## U parent-u...
parent:

                        ## Pozivamo getpid() da nam vrati PID parent procesa.
                        ## Prethodno cuvamo vrednost eax, zato sto zelimo da
                        ## kasnije iskoristimo vrednost koju je fork() vratio.
    mov     r12d, eax
    call    getpid

                        ## Pozivamo printf() da nam ispise parend PID
    lea     rdi, ppmsg
    mov     esi, eax
    call    printf

                        ## Pozivamo printf() da nam ispise child PID
                        ## Child PID je vec na steku, jer je to upravo
                        ## vrednost koju fork() vraca parent-u, a koju
                        ## smo malo pre sacuvali na steku.
    lea     rdi, cpmsg
    mov     esi, r12d
    call    printf
    jmp     done

                        ##  U child-u...
child:

                        ## Uspavljujemo proces na dve sekunde, kako bismo
                        ## dali prednost parent procesu da se prvi izvrsi.
                        ## U ovom slucaju init proces postaje parent child-a
    ## mov     rdi, 2
    ## call    sleep

                        ## Pozivamo getppid() da nam vrati parent PID
    call    getppid

                        ## Pozivamo printf() da nam prikaze parent PID.
    lea     rdi,pcmsg
    mov     esi, eax
    call    printf

                        ## Pozivamo getpid() da nam vrati PID child-a.
    call    getpid

                        ##  Pozivamo printf() da nam prikaze child PID.
    lea     rdi, ccmsg
    mov     esi, eax
    call    printf

done:
    leave
    ret

