//----------------------------------------------------------------- // run.s // // This program demonstrates the 'fork()', 'waitpid()', and // 'execve()' system-calls, and shows how a 'child' process // communicates the value of its exit-code to the 'parent'. // // to assemble: $ as run.s -o run.o // and to link: $ ld run.o -o run // and execute: $ ./run [...] // // programmer: ALLAN CRUSE // written on: 26 FEB 2008 //----------------------------------------------------------------- # manifest constants .equ sys_execve, 11 .equ sys_waitpid, 7 .equ sys_write, 4 .equ sys_fork, 2 .equ sys_exit, 1 .equ STDOUT, 1 .section .data hex: .ascii "0123456789ABCDEF" # array of hex numerals ret: .int -1 # storage for exit-code msg: .ascii "\nChild-process terminated with exit-code = 0x" buf: .ascii "xx \n\n" # buffer for hex string len: .int . - msg # size of output string .section .text _start: # fork a child-process mov $sys_fork, %eax # system-call ID-number int $0x80 # invoke kernel service # parent waits while child launches the application or %eax, %eax # parent process? jz child # no, skip waiting # wait until child-process has terminated mov $sys_waitpid, %eax # system-call ID-number mov $0, %ebx # PID is unspecified lea ret, %ecx # where to save status int $0x80 # invoke kernel service # convert exit-status to hexadecimal digit-string lea buf, %edi # output-buffer address mov ret, %eax # get child's exit-code call ah2hex # convert int to string # display the report mov $sys_write, %eax # system-call ID-number mov $STDOUT, %ebx # device-file ID-number lea msg, %ecx # address of the string mov len, %edx # length for the string int $0x80 # invoke kernel service # terminate the parent-process xor %ebx, %ebx # parent exit-code = 0 exit: mov $sys_exit, %eax # system-call ID-number int $0x80 # invoke kernel service child: # child-process executes the specified application cmpl $1, (%esp) # user supplied name? je exit # no, cannot continue mov $sys_execve, %eax # system-call ID-number mov 8(%esp), %ebx # address of prog name lea 8(%esp), %ecx # address of argv mov (%esp), %esi # value of argc lea 8(%esp, %esi, 4), %edx # address of envp int $0x80 # invoke kernel service # in case of failure, the child-process terminates mov %eax, %ebx # errno is exit-code jmp exit # and terminate child # # This helper-function converts an 8-bit value it finds in the # AH register into its representation as a pair of hexadecimal # numerals in the memory-buffer whose address it finds in EDI. # ah2hex: pushal mov $2, %ecx nxnyb: rol $4, %ax mov %al, %bl and $0xF, %ebx mov hex(%ebx), %dl mov %dl, (%edi) inc %edi loop nxnyb popal ret .global _start .end