.data
formatString: .asciz "%s"
descLabel: .asciz "File Descriptor: %dn"
sizeLabel: .asciz "File Size: %d kilobytesnn"
afis_nr: .asciz "%d n"
# Buffers and variables
path: .space 256
dirPtr: .space 4 # pointer to DIR structure
dirEntryPtr: .space 4 # pointer to dirent structure
.text
CONCRETE:
pushl %ebp
movl %esp, %ebp
leal path, %edi # address of the path buffer
pushl %edi
call opendir
addl $4, %esp
movl %eax, dirPtr
read_dir:
movl dirPtr, %edi
pushl %edi
call readdir
addl $4, %esp
testl %eax, %eax # check if null
je close_dir
movl %eax, dirEntryPtr # save dirent* pointer
# get the d_name field of dirent
movl dirEntryPtr, %edi
addl $11, %edi # address of d_name in dirent
pushl %edi # open the file using d_name
call open
addl $4, %esp
movl %eax, %ebx # save file descriptor
pushl %ebx # print file descriptor
pushl $descLabel
call printf
addl $8, %esp
# get file size with lseek
movl $8, %eax
movl %ebx, %edi # file descriptor
xorl %esi, %esi # offset
movl $2, %edx # SEEK_END
int $0x80
movl %eax, %ecx # save file size
addl $1023, %ecx # calculate file size in kilobytes
shrl $10, %ecx # divide by 1024
pushl %ecx # print file size
pushl $sizeLabel
call printf
addl $8, %esp
movl $3, %eax # syscall: close
movl %ebx, %edi
int $0x80
jmp read_dir
close_dir:
movl dirPtr, %edi
pushl %edi
call closedir
addl $4, %esp
exit_CONCRETE:
popl %ebp
ret
.global main
main:
pushl $path
pushl $formatString
call scanf
addl $8, %esp
call CONCRETE
movl $1, %eax
xorl %ebx, %ebx
int $0x80
I want to have the code print the file descriptor and size (in kilobytes), but for a folder that is given as “input” with 16 .txt files, I get 18 outputs, 16 of them having the descriptor return with -1, and the size not being calculated properly; I’m very new to assembly languages, so I suppose there must be something wrong with the offset?
# get the d_name field of dirent
movl dirEntryPtr, %edi
addl $11, %edi # address of d_name in dirent
maybe something wrong here?
I see at least three problems:
- The paths you get from
readdir
are relative to the directory you calledreaddir
on, but the paths you pass toopen
need to be relative to the current directory. - You’re using the syscall numbers from x86_64 even though you’re targeting 32-bit x86.
- Your code runs on both files and directories, but
lseek
on a directory isn’t a valid way of getting its size.