//----------------------------------------------------------------- // 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 //----------------------------------------------------------------- # manifest constants .equ sys_EXIT, 1 .equ sys_WRITE, 4 .equ STDOUT, 1 .equ EOLN, '\n' .section .data target: .ascii "USER=" # the string to look for tarlen: .int . - target # target string's length uname: .zero 40 # for storing a username usize: .int 0 # for length of username .section .text _start: # get the array-index for the first environment-string mov (%esp), %ebx # count of cmdline strings inc %ebx # add one for null-pointer inc %ebx # plus one for arg-counter # loop to search for the 'USER=' environment-variable nxenv: cmpl $0, (%esp, %ebx, 4) # found a null-pointer? je finis # yes, search is ended # compare target to next environment-variable string mov (%esp, %ebx, 4), %esi # pointer to next variable lea target, %edi # pointer to target string mov tarlen, %ecx # length of target string cld # do forward processing rep cmpsb # variable matches target? je found # yes, search succeeded inc %ebx # else advance the index jmp nxenv # and continue searching found: # search for the environment-string's null-byte mov %esi, %edi # point EDI to string xor %al, %al # setup the target-byte mov $39, %ecx # setup maximum length cld # do forward processing repne scasb # scan for matching byte # calculate and store the string's length sub %esi, %edi # subtract start-address mov %edi, usize # store resulting length # copy environment-variable's string-value to our buffer lea uname, %edi # destination's address mov usize, %ecx # 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 %edi # back up past null-byte stosb # overwrite that byte # display the environment-variable's string-value mov $sys_WRITE, %eax # system-call ID-number mov $STDOUT, %ebx # device-file ID-number lea uname, %ecx # pointer to the buffer mov usize, %edx # count of buffer bytes int $0x80 # invoke kernel service finis: # terminate this program mov $sys_EXIT, %eax # system-call ID-number xor %ebx, %ebx # use zero as exit-code int $0x80 # invoke kernel service .global _start # make entry-point public .end # no more to be assembled