12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- .text # Section for machine istructions to be executed
- .global _start # Needed by ld to find his default entry point
- _start: # _start symbol
- mov $257, %rax # sys_openat call
- mov $-100, %rdi # Set dir file descriptor. -100 is special for
- # AT_FDCWD (fd of current dir)
- mov $cwd, %rsi # Set filename
- xor %rdx, %rdx # Call kernel
- syscall # Set file status flag. 0 = O_RDONLY
- test %rax, %rax # Test return value. Negative is failure.
- # Anithing else is dir file descriptor
- js exit_error # If signed jump to error
- mov %rax, %rdi # Set dir file descriptor
- mov $217, %rax # sys_getdents64 call
- mov $buf, %rsi # Set pointer to buffer for storing dir entries
- mov $ 16777216, %rdx # Set buffer length
- syscall # Call kernel
- test %rax, %rax # Negative is error. Anything else is number of
- # bytes read
- js exit_error
- mov %rax, %r12 # Save number of bytes read
- mov %rsi, %r13 # Save buffer pointer
- dirent_loop: # Loop over directory entries
- lea 19(%r13), %r15 # Save pointer to filename
- mov %r15, %rdi # Set pointer to filename
- xor %rcx, %rcx # Set %rdx to zero
- xor %al, %al # Set %al to zero
- not %rcx # Set %rdx to max integer (not of 0)
- cld # Set direction flag to zero.
- # When direction flag is set to zero all string istructions
- # run ahead (from low to high adresses)
- repne scasb # repne = repeat argument operation %rcx times unless
- # confronted areas are equal, decrementing %rcx each time.
- # scasb = compare %al with byte at %rdi then set status flags.
- # In other words: search zero byte at the and of the string.
- not %rcx # Now %rcx is max int - filename_length - 1 (zero byte).
- # But max int = -1 so %rcx = -2 - filename_length and
- # Note that not number is abs(number) - 1,
- # so %rcx = filename_length + 2 -1 = filename_length + 1
- dec %rcx # Decrease %rcx so that now %rcx = filename_length
- mov $1, %rax # Print filename to stdout
- mov $1, %rdi
- mov %r15, %rsi
- mov %rcx, %rdx
- syscall
- mov $1, %rax # Print endline to stdout
- mov $endl, %rsi
- mov $1, %rdx
- syscall
- movw 16(%r13), %r14w # Save size of current entry in low word of %r14
- add %r14, %r13 # Add size to buffer pointer to shift to next entry
- sub %r14, %r12 # Subtract size from buffer size
- test %r12, %r12 # Test if left buffer size is zero
- jnz dirent_loop # Loop if nonzero
- exit: # Exit success
- mov $60, %rax
- xor %rdi, %rdi
- syscall
- exit_error: # Exit failure
- mov $60, %rax
- mov $1, %rdi
- syscall
- .section .rodata
- cwd: # Variable for current dir (.)
- .asciz "."
- endl: # Variable for endline
- .byte '\n'
- .section .bss
- buf: # Dir entries buffer.
- # Attention! This sets a limit to entries
- # read from dir.
- .skip 16777216 # 16 MiB
|