# ;; basename.s # # #include .data eoln: .string "\n" slash: .string "/" period: .string ".\n" slash_found_p: # this is a flag .double 0 zero_byte_location: # this is a location, so need four bytes .double 0 basename_start: # this is where the basename actually starts .double 0 argc: # save the argument count .double 0 # # # .file "basename.s" .text .globl basename basename: cmp $1,(%esp) # check to see if there are no arguments je exit # registers used: # eax = utility # ebx = pointer to beginning of argument --> but we will also need to setup for writestr as fd # ecx = used to call writestr (it's the string pointer...) # edx = pointer to latest slash # esi = # edi = pop %ebx # save the argument count in argc mov %ebx,argc # should check to make sure that there is an argument! pop %ebx # remove the command line pop %ebx # %ebx now has pointer to beginning of first argument (should make sure that # argc is big enough ... ) mov %ebx,%edx # %edx also has the beginning for now, but if we find a slash, we update %edx # to the location of the slash movb slash,%cl # put slash character into %cl so we can make comparison name_loop: cmpb $0,(%ebx) # is the byte a zero? then we are finished looking at the command jz found_zero_byte cmpb %cl,(%ebx) # is it a slash? then we save our position je found_a_slash inc %ebx jmp name_loop found_a_slash: mov %ebx,%edx # save position in %edx inc %ebx # increment %ebx movb $1,slash_found_p # set flag that we found it jmp name_loop found_zero_byte: # save %ebx in zero_byte_location --- that's the location of the last (zero) byte mov %ebx,zero_byte_location # did we find it? if not, then output whole original argument cmp $0,slash_found_p jne found_last_slash # save first byte in basename_start --- the double move is because i386 doesn't support this in a single step mov %edx,basename_start jmp check_for_suffix found_last_slash: # save first byte in basename_start mov %edx,basename_start incl basename_start check_for_suffix: cmp $3,argc # well, we have another argument, it must indicate a suffix that we want to try to remove jl done # let's find that zero byte! cld # go forward mov $0,%al # put zero in %al pop %ebp # save our pointer to this argument in %ebp mov %ebp,%edi # and copy it to %edi mov $1000,%ecx # arbitrarily cap this... repne scasb jne done # we give up if we didn't find a zero byte in 1000 bytes... (That would be a very unusual suffix!) dec %edi # scasb actually puts us one byte beyond sub %ebp,%edi # take the difference sub %edi,zero_byte_location # now take that difference to reduce zero_byte_location # finally, do a comparison of zero_byte_location and %eax cld mov %edi,%ecx # remember, the difference (i.e., the number of bytes in arg3) # was left in %edi mov %ebp,%esi # now arrange arg3 pointer into %esi mov zero_byte_location,%edi # and put the "beginning" of bytes into %edi rep cmpsb jne done mov zero_byte_location,%eax # since we cannot apparently do a pure relative mov $0,(zero_byte_location) movb $0,(%eax) # terminate string at the beginning of the suffix done: mov basename_start,%ecx # now point %ecx back to slash + 1 mov $1,%ebx call writestr lea eoln,%ecx # don't forget to send an eoln also mov $1,%ebx call writestr exit: mov $0, %ebx # and exit with a zero status mov $__NR_exit,%eax # exit int $0x80