|
@@ -0,0 +1,82 @@
|
|
|
+.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
|