//----------------------------------------------------------------- // mywhoami.s // // This example illustrates the use of string-manipulation // instructions: (1) to search for an environment variable // by performing a string-comparison, (2) to scan an asciz // string for its null-byte, and (3) to copy a string into // a local buffer-area where (4) a 'line-feed' code can be // appended and then the resulting string can be displayed. // // to assemble: $ as mywhoami.s -o mywhoami.o // and to link: $ ld mywhoami.o -o mywhoami // // programmer: ALLAN CRUSE // written on: 31 MAR 2007 // revised on: 01 MAR 2009 -- for x86_64 Linux platform //----------------------------------------------------------------- # manifest constants .equ sys_EXIT, 60 .equ sys_WRITE, 1 .equ STDOUT, 1 .equ EOLN, '\n' .section .data target: .ascii "USER=" # the string to look for tarlen: .quad . - target # target string's length uname: .zero 40 # for storing a username usize: .quad 0 # for length of username .section .text _start: # get the array-index for the first environment-string mov (%rsp), %rbx # count of cmdline strings inc %rbx # add one for null-pointer inc %rbx # plus one for arg-counter # loop to search for the 'USER=' environment-variable nxenv: cmpq $0, (%rsp, %rbx, 8) # found a null-pointer? je finis # yes, search is ended # compare target to next environment-variable string mov (%rsp, %rbx, 8), %rsi # pointer to next variable lea target, %rdi # pointer to target string mov tarlen, %rcx # length of target string cld # do forward processing rep cmpsb # variable matches target? je found # yes, search succeeded inc %rbx # else advance the index jmp nxenv # and continue searching found: # search for the environment-string's null-byte mov %rsi, %rdi # point EDI to string xor %al, %al # setup the target-byte mov $39, %rcx # setup maximum length cld # do forward processing repne scasb # scan for matching byte # calculate and store the string's length sub %rsi, %rdi # subtract start-address mov %rdi, usize # store resulting length # copy environment-variable's string-value to our buffer lea uname, %rdi # destination's address mov usize, %rcx # count of bytes to copy cld # do forward processing rep movsb # perform string copying # append a 'line-feed' code to string's non-null bytes mov $EOLN, %al # setup the ascii-code dec %rdi # back up past null-byte stosb # overwrite that byte # display the environment-variable's string-value mov $sys_WRITE, %rax # system-call ID-number mov $STDOUT, %rdi # device-file ID-number lea uname, %rsi # pointer to the buffer mov usize, %rdx # count of buffer bytes syscall # invoke kernel service finis: # terminate this program mov $sys_EXIT, %rax # system-call ID-number xor %rdi, %rdi # use zero as exit-code syscall # invoke kernel service .global _start # make entry-point public .end # no more to be assembled