//---------------------------------------------------------------- // forkdemo.s // // This program illustrates the Linux 'fork' and 'waitpid' // system-calls. The parent-process forks a child-process // which displays a message and then terminates, while the // parent waits for its child to finish. After the parent // resumes execution, it displays its child's exit-status. // // assemble using: $ as forkdemo.s -o forkdemo.o // and link using: $ ld forkdemo.o eax2hex.o -o forkdemo // // programmer: ALLAN CRUSE // written on: 19 FEB 2006 //---------------------------------------------------------------- # manifest constants .equ sys_exit, 1 .equ sys_fork, 2 .equ sys_write, 4 .equ sys_waitpid, 7 .equ STDOUT, 1 .equ OPTIONS, 0 .section .data pid: .space 4 # holds fork return-value status: .space 4 # holds child exit-status msg1: .ascii "\nChild-process says \'Hello\' \n" len1: .int . - msg1 # length of child message msg2: .ascii "\nParent-process says " .ascii "'\Child-process terminated with status=" buf1: .ascii "xxxxxxxx\' \n\n" len2: .int . - msg2 # length of parent message .section .text _start: # fork a 'child' process movl $sys_fork, %eax # setup the service-ID int $0x80 # invoke kernel service movl %eax, pid # save the return-value # control branches to parent or child cmpl $0, pid # did 'fork' return zero? je child # yes, child is executing jmp parent # else parent is executing child: # display a confirmation message movl $sys_write, %eax # setup the service-ID movl $STDOUT, %ebx # specify the device-ID leal msg1, %ecx # point to child message movl len1, %edx # length of this message int $0x80 # invoke kernel service # terminate the child process movl $sys_exit, %eax # setup the service-ID movl $0x12345678, %ebx # specify the exit-code int $0x80 # invoke kernel service parent: # wait for the child to finish movl $sys_waitpid, %eax # setup the service-ID movl pid, %ebx # specify the process-ID leal status, %ecx # point to status variable movl $OPTIONS, %edx # specify the 'wait' flags int $0x80 # invoke kernel service # format message #2 movl status, %eax # load 'status' into EAX leal buf1, %edi # point EDI to dst'n field call eax2hex # convert number to string # display parent's report movl $sys_write, %eax # setup the service-ID movl $STDOUT, %ebx # specify the device-ID leal msg2, %ecx # point to parent message movl len2, %edx # length of this message int $0x80 # invoke kernel service # terminate the parent process movl $sys_exit, %eax # setup the service-ID movl $0, %ebx # specify the exit-code int $0x80 # invoke kernel service .global _start # make entry-point visible .end # nothing more to assemble