# ;; ls.s # # # #include .file "ls.s" .data argc: .long 0 argv: .long 0 # location of the current argument fd: .long 0 dirname: .string "/usr/lib" open_flags: .quad 00200000 # .quad O_DIRECTORY | O_RDONLY eoln: .string "\n" separator: .string " " .align 4 direntries: .space 4096,0 bytes_received: .long 0 .text .global ls ls: # walk through arglist, see if you can open files... nop pop argc pop %eax dec argc jz _finish _nextarg: pop %ebx # load directory name into %rdi mov open_flags,%ecx mov $__NR_open,%eax int $0x80 cmp $0,%eax jl _next # save the file descriptor in fd (%r15) mov %eax,fd lea direntries,%r14 # clear %r8 - %r9 # xor %r8,%r8 # going to use this to walk direntries xor %rsi,%rsi # xor %r9,%r9 # going to calculate offset to next dirent xor %rdi,%rdi # xor %r10,%r10 # going to use save how many bytes did we receive from getdents _read_entries: mov fd,%ebx # recover file descriptor from %r15 lea direntries,%ecx # point %rsi at direntries mov $4096,%edx mov $__NR_getdents,%eax int $0x80 cmp $0,%eax jle _finish mov %eax,bytes_received call _process_entries # close the file descriptor... mov %r15,%rdi mov $__NR_close,%rax int $0x80 _next: dec %r13 jnz _nextarg _finish: mov $0,%rdi # and exit with a zero status mov $__NR_exit,%rax # syscall = 60 is exit int $0x80 # # process_entries # # # we have been handed a block of entries in 'direntries' # # step through each one, and call appropriate handler for # each individual one... # _process_entries: lea direntries,%rsi # %rsi has the current dirent _around: call _entry_raw # is there a next? mov 16(%rsi),%rdiw # okay, %rdiw has distance to next add %rdi,%rsi mov %rsi,%r12 # check to see if we have processed all bytes... sub %r14,%r12 # %r14 should have value of direntries cmp %r10,%r12 jl _around ret # # entry_raw # # this is the most basic handler --> all that it does is send an # entry out to stdout # _entry_raw: mov $1,%ebx lea 18(%rsi),%ecx call writestr mov $1,%ebx lea eoln,%ecx call writestr ret