//----------------------------------------------------------------- // 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 // revised on: 01 MAR 2009 -- for our x86_64 Linux platform //----------------------------------------------------------------- # manifest constants .equ sys_write, 1 .equ sys_fork, 57 .equ sys_execve, 59 .equ sys_exit, 60 .equ sys_wait4, 61 .equ STDOUT, 1 .section .data hex: .ascii "0123456789ABCDEF" # array of hex numerals ret: .quad -1 # storage for exit-code msg: .ascii "\nChild-process terminated with exit-code = 0x" buf: .ascii "xx \n\n" # buffer for hex string len: .quad . - msg # size of output string .section .text _start: # fork a child-process mov $sys_fork, %rax # system-call ID-number syscall # invoke kernel service # parent waits while child launches the application or %rax, %rax # parent process? jz child # no, skip waiting # wait until child-process has terminated mov $sys_wait4, %rax # system-call ID-number mov $0, %rdi # PID is unspecified lea ret, %rsi # where to save status mov $0, %rdx # no special options xor %rbx, %rbx # no 'rusage' structure syscall # invoke kernel service # convert exit-status to hexadecimal digit-string lea buf, %rdi # output-buffer address mov ret, %rax # get child's exit-code call ah2hex # convert int to string # display the report mov $sys_write, %rax # system-call ID-number mov $STDOUT, %rdi # device-file ID-number lea msg, %rsi # address of the string mov len, %rdx # length for the string syscall # invoke kernel service # terminate the parent-process xor %rdi, %rdi # parent exit-code = 0 exit: mov $sys_exit, %rax # system-call ID-number syscall # invoke kernel service child: # child-process executes the specified application cmpl $1, (%rsp) # user supplied name? je exit # no, cannot continue mov $sys_execve, %rax # system-call ID-number mov 16(%rsp), %rdi # address of prog name lea 16(%rsp), %rsi # address of argv mov (%rsp), %rdx # value of argc lea 16(%rsp, %rdx, 8), %rdx # address of envp syscall # invoke kernel service # in case of failure, the child-process terminates mov %rax, %rdi # 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 RDI. # ah2hex: push %rax push %rbx push %rcx push %rdx push %rdi mov $2, %rcx nxnyb: rol $4, %ax mov %al, %bl and $0xF, %rbx mov hex(%rbx), %dl mov %dl, (%rdi) inc %rdi loop nxnyb pop %rdi pop %rdx pop %rcx pop %rbx pop %rax ret .global _start .end