flat assembler
Message board for the users of flat assembler.

Index > Main > Problems with finding files in linux

Author
Thread Post new topic Reply to topic
alphv



Joined: 26 Dec 2024
Posts: 5
alphv 26 Dec 2024, 16:49
Hello! I have a code that should search for files in the current directory, but it does not search for anything and does not output their names to the console. What's wrong with the code? Maybe someone has some workpieces? Thank you.

Code:
format ELF64 executable 3

segment readable executable

entry $

    ; Open the current directory
    mov eax, 2          ; sys_open
    lea rdi, [dir_path] ; path to the current directory
    mov rsi, 0          ; flags (O_RDONLY)
    mov rdx, 0          ; mode (not used)
    syscall

    cmp eax, 0          ; check if the directory was opened successfully
    jl .exit            ; if not, exit

    mov [dir_fd], eax   ; save the directory file descriptor

.read_dir:
    ; Read the next directory entry
    mov eax, 78         ; sys_getdents64
    mov edi, [dir_fd]   ; directory file descriptor
    lea rsi, [dir_buf]  ; buffer for reading
    mov rdx, 1024       ; buffer size
    syscall

    cmp eax, 0          ; check if the read was successful
    jle .close_dir      ; if not, close the directory

    ; Process the read data
    lea rbx, [dir_buf]  ; start of the buffer
    add rax, rbx        ; end of the buffer

.process_entry:
    ; Get the file name
    lea rsi, [rbx + 19] ; d_name in the linux_dirent64 structure
    movzx rdx, word [rbx + 16] ; d_reclen (record length)

    ; Skip entries "." and ".."
    cmp byte [rsi], '.'
    je .next_entry

    ; Check the file extension
    call check_extension
    test rax, rax
    jz .next_entry      ; if the extension doesn't match, skip the file

    ; Print the file name with a new line
    mov eax, 1          ; sys_write
    mov edi, 1          ; STDOUT
    mov rcx, rsi        ; pointer to the file name
    call strlen         ; get the length of the file name
    mov rdx, rax        ; length of the file name
    syscall

    ; Print a newline character
    mov eax, 1          ; sys_write
    mov edi, 1          ; STDOUT
    lea rsi, [newline]  ; newline character
    mov rdx, 1          ; length of the newline character
    syscall

.next_entry:
    ; Move to the next entry
    add rbx, rdx        ; move to the next record
    cmp rbx, rax        ; check if we reached the end of the buffer
    jl .process_entry   ; if not, continue processing

    jmp .read_dir       ; read the next chunk of data

.close_dir:
    ; Close the directory
    mov eax, 3          ; sys_close
    mov edi, [dir_fd]   ; directory file descriptor
    syscall

.exit:
    ; Exit the program
    xor edi, edi        ; exit code 0
    mov eax, 60         ; sys_exit
    syscall

; Function to check the file extension
check_extension:
    mov rdi, rsi        ; pointer to the file name
    call strlen         ; get the length of the file name
    cmp rax, 4          ; minimum file name length for an extension
    jl .invalid_ext     ; if the name is too short, skip
    lea rdi, [rsi + rax - 4] ; pointer to the last 4 characters (extension)
    lea rsi, [txt_ext]  ; .txt extension
    call strcmp
    test rax, rax
    jz .valid_ext
    lea rsi, [jpg_ext]  ; .jpg extension
    call strcmp
    test rax, rax
    jz .valid_ext
.invalid_ext:
    xor rax, rax        ; extension doesn't match
    ret
.valid_ext:
    mov rax, 1          ; extension matches
    ret

; Function to compare strings
strcmp:
    mov rcx, 4          ; length of the extension
.loop:
    mov al, [rdi]
    mov bl, [rsi]
    cmp al, bl
    jne .not_equal
    inc rdi
    inc rsi
    loop .loop
    xor rax, rax        ; strings are equal
    ret
.not_equal:
    mov rax, 1          ; strings are not equal
    ret

; Function to calculate the length of a string
strlen:
    xor rax, rax
.loop:
    cmp byte [rdi + rax], 0
    je .done
    inc rax
    jmp .loop
.done:
    ret

segment readable writeable

dir_path db '.', 0      ; current directory path
dir_fd dd 0             ; directory file descriptor
dir_buf rb 1024         ; buffer for directory entries
newline db 10           ; newline character
txt_ext db '.txt', 0    ; .txt extension
jpg_ext db '.jpg', 0    ; .jpg extension    
Post 26 Dec 2024, 16:49
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1041
Location: Russia
macomics 26 Dec 2024, 18:20
Code:
    lea rsi, [rbx + 18] ; d_name in the linux dirent64 structure
;                    ^- not 19    


and more simple errors...

Code:
format ELF64 executable 3

segment readable executable

entry $

    ; Open the current directory
    mov eax, 2          ; sys_open
    lea rdi, [dir_path] ; path to the current directory
    mov rsi, 0          ; flags (O_RDONLY)
    mov rdx, 0          ; mode (not used)
    syscall

    cmp eax, 0          ; check if the directory was opened successfully
    jl .exit            ; if not, exit

    mov [dir_fd], eax   ; save the directory file descriptor

.read_dir:
    ; Read the next directory entry
    mov eax, 78         ; sys_getdents64
    mov edi, [dir_fd]   ; directory file descriptor
    lea rsi, [dir_buf]  ; buffer for reading
    mov rdx, 1024       ; buffer size
    syscall

    cmp eax, 0          ; check if the read was successful
    jle .close_dir      ; if not, close the directory

    ; Process the read data
    lea rbx, [dir_buf]  ; start of the buffer
    add rax, rbx        ; end of the buffer

.process_entry:
    ; Get the file name
    lea rsi, [rbx + 18] ; d_name in the linux_dirent64 structure
    movzx rdx, word [rbx + 16] ; d_reclen (record length)

    ; Skip entries "." and ".."
    cmp byte [rsi], '.'
    je .next_entry

    ; Check the file extension
    call check_extension
    test rax, rax
    jz .next_entry      ; if the extension doesn't match, skip the file

    ; Print the file name with a new line
    mov rcx, rsi        ; pointer to the file name
    call strlen         ; get the length of the file name
    mov rdx, rax        ; length of the file name
    mov rdi, 1          ; STDOUT
    mov eax, 1          ; sys_write
    syscall

    ; Print a newline character
    mov eax, 1          ; sys_write
    mov rdi, 1          ; STDOUT
    lea rsi, [newline]  ; newline character
    mov rdx, 1          ; length of the newline character
    syscall

.next_entry:
    ; Move to the next entry
    add rbx, rdx        ; move to the next record
    cmp rbx, rax        ; check if we reached the end of the buffer
    jl .process_entry   ; if not, continue processing

    jmp .read_dir       ; read the next chunk of data

.close_dir:
    ; Close the directory
    mov eax, 3          ; sys_close
    mov edi, [dir_fd]   ; directory file descriptor
    syscall

.exit:
    ; Exit the program
    xor edi, edi        ; exit code 0
    mov eax, 60         ; sys_exit
    syscall

; Function to check the file extension
check_extension:
    push rsi
    mov rdi, rsi        ; pointer to the file name
    mov rcx, rsi
    call strlen         ; get the length of the file name
    cmp rax, 4          ; minimum file name length for an extension
    jl .invalid_ext     ; if the name is too short, skip
    lea rdi, [rsi + rax - 4] ; pointer to the last 4 characters (extension)
    lea rsi, [txt_ext]  ; .txt extension
    call strcmp
    test rax, rax
    jz .valid_ext
    lea rsi, [jpg_ext]  ; .jpg extension
    call strcmp
    test rax, rax
    jz .valid_ext
.invalid_ext:
    xor rax, rax        ; extension doesn't match
    pop rsi
    ret
.valid_ext:
    mov rax, 1          ; extension matches
    pop rsi
    ret

; Function to compare strings
strcmp:
    mov rcx, 4          ; length of the extension
    xor rax, rax
.loop:
    mov dl, [rdi + rax]
    cmp dl, [rsi + rax]
    jne .not_equal
    inc rax
    loop .loop
    xor rax, rax        ; strings are equal
    ret
.not_equal:
    mov rax, 1          ; strings are not equal
    ret

; Function to calculate the length of a string
strlen:
    xor rax, rax
.loop:
    cmp byte [rcx + rax], 0
    je .done
    inc rax
    jmp .loop
.done:
    ret

segment readable writeable

dir_path db '.', 0      ; current directory path
dir_fd dd 0             ; directory file descriptor
dir_buf rb 1024         ; buffer for directory entries
newline db 10           ; newline character
txt_ext db '.txt', 0    ; .txt extension
jpg_ext db '.jpg', 0    ; .jpg extension    
Post 26 Dec 2024, 18:20
View user's profile Send private message Reply with quote
alphv



Joined: 26 Dec 2024
Posts: 5
alphv 26 Dec 2024, 18:57
thanks Smile
macomics wrote:
Code:
    lea rsi, [rbx + 18] ; d_name in the linux dirent64 structure
;                    ^- not 19    


and more simple errors...

Code:
format ELF64 executable 3

segment readable executable

entry $

    ; Open the current directory
    mov eax, 2          ; sys_open
    lea rdi, [dir_path] ; path to the current directory
    mov rsi, 0          ; flags (O_RDONLY)
    mov rdx, 0          ; mode (not used)
    syscall

    cmp eax, 0          ; check if the directory was opened successfully
    jl .exit            ; if not, exit

    mov [dir_fd], eax   ; save the directory file descriptor

.read_dir:
    ; Read the next directory entry
    mov eax, 78         ; sys_getdents64
    mov edi, [dir_fd]   ; directory file descriptor
    lea rsi, [dir_buf]  ; buffer for reading
    mov rdx, 1024       ; buffer size
    syscall

    cmp eax, 0          ; check if the read was successful
    jle .close_dir      ; if not, close the directory

    ; Process the read data
    lea rbx, [dir_buf]  ; start of the buffer
    add rax, rbx        ; end of the buffer

.process_entry:
    ; Get the file name
    lea rsi, [rbx + 18] ; d_name in the linux_dirent64 structure
    movzx rdx, word [rbx + 16] ; d_reclen (record length)

    ; Skip entries "." and ".."
    cmp byte [rsi], '.'
    je .next_entry

    ; Check the file extension
    call check_extension
    test rax, rax
    jz .next_entry      ; if the extension doesn't match, skip the file

    ; Print the file name with a new line
    mov rcx, rsi        ; pointer to the file name
    call strlen         ; get the length of the file name
    mov rdx, rax        ; length of the file name
    mov rdi, 1          ; STDOUT
    mov eax, 1          ; sys_write
    syscall

    ; Print a newline character
    mov eax, 1          ; sys_write
    mov rdi, 1          ; STDOUT
    lea rsi, [newline]  ; newline character
    mov rdx, 1          ; length of the newline character
    syscall

.next_entry:
    ; Move to the next entry
    add rbx, rdx        ; move to the next record
    cmp rbx, rax        ; check if we reached the end of the buffer
    jl .process_entry   ; if not, continue processing

    jmp .read_dir       ; read the next chunk of data

.close_dir:
    ; Close the directory
    mov eax, 3          ; sys_close
    mov edi, [dir_fd]   ; directory file descriptor
    syscall

.exit:
    ; Exit the program
    xor edi, edi        ; exit code 0
    mov eax, 60         ; sys_exit
    syscall

; Function to check the file extension
check_extension:
    push rsi
    mov rdi, rsi        ; pointer to the file name
    mov rcx, rsi
    call strlen         ; get the length of the file name
    cmp rax, 4          ; minimum file name length for an extension
    jl .invalid_ext     ; if the name is too short, skip
    lea rdi, [rsi + rax - 4] ; pointer to the last 4 characters (extension)
    lea rsi, [txt_ext]  ; .txt extension
    call strcmp
    test rax, rax
    jz .valid_ext
    lea rsi, [jpg_ext]  ; .jpg extension
    call strcmp
    test rax, rax
    jz .valid_ext
.invalid_ext:
    xor rax, rax        ; extension doesn't match
    pop rsi
    ret
.valid_ext:
    mov rax, 1          ; extension matches
    pop rsi
    ret

; Function to compare strings
strcmp:
    mov rcx, 4          ; length of the extension
    xor rax, rax
.loop:
    mov dl, [rdi + rax]
    cmp dl, [rsi + rax]
    jne .not_equal
    inc rax
    loop .loop
    xor rax, rax        ; strings are equal
    ret
.not_equal:
    mov rax, 1          ; strings are not equal
    ret

; Function to calculate the length of a string
strlen:
    xor rax, rax
.loop:
    cmp byte [rcx + rax], 0
    je .done
    inc rax
    jmp .loop
.done:
    ret

segment readable writeable

dir_path db '.', 0      ; current directory path
dir_fd dd 0             ; directory file descriptor
dir_buf rb 1024         ; buffer for directory entries
newline db 10           ; newline character
txt_ext db '.txt', 0    ; .txt extension
jpg_ext db '.jpg', 0    ; .jpg extension    
Post 26 Dec 2024, 18:57
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1041
Location: Russia
macomics 26 Dec 2024, 19:10
and more...
Code:
format ELF64 executable 3

segment readable executable

entry $

    ; Open the current directory
    mov eax, 2          ; sys_open
    lea rdi, [dir_path] ; path to the current directory
    mov rsi, 0          ; flags (O_RDONLY)
    mov rdx, 0          ; mode (not used)
    syscall

    cmp eax, 0          ; check if the directory was opened successfully
    jl .exit            ; if not, exit

    mov [dir_fd], eax   ; save the directory file descriptor

.read_dir:
    ; Read the next directory entry
    mov eax, 78         ; sys_getdents64
    mov edi, [dir_fd]   ; directory file descriptor
    lea rsi, [dir_buf]  ; buffer for reading
    mov rdx, 1024       ; buffer size
    syscall

    cmp eax, 0          ; check if the read was successful
    jle .close_dir      ; if not, close the directory

    ; Process the read data
    lea rbx, [dir_buf]  ; start of the buffer
    lea r8, [rax+rbx]        ; end of the buffer

.process_entry:
    ; Get the file name
    lea rsi, [rbx + 18] ; d_name in the linux_dirent64 structure

    ; Skip entries "." and ".."
    cmp byte [rsi], '.'
    je .next_entry

    ; Check the file extension
    call check_extension
    test rax, rax
    jz .next_entry      ; if the extension doesn't match, skip the file

    ; Print the file name with a new line
    mov rcx, rsi        ; pointer to the file name
    call strlen         ; get the length of the file name
    mov rdx, rax        ; length of the file name
    mov rdi, 1          ; STDOUT
    mov eax, 1          ; sys_write
    syscall

    ; Print a newline character
    mov eax, 1          ; sys_write
    mov rdi, 1          ; STDOUT
    lea rsi, [newline]  ; newline character
    mov rdx, 1          ; length of the newline character
    syscall

.next_entry:
    ; Move to the next entry
    movzx rdx, word [rbx + 16] ; d_reclen (record length)
    add rbx, rdx        ; move to the next record
    cmp rbx, r8        ; check if we reached the end of the buffer
    jl .process_entry   ; if not, continue processing

    jmp .read_dir       ; read the next chunk of data

.close_dir:
    ; Close the directory
    mov eax, 3          ; sys_close
    mov edi, [dir_fd]   ; directory file descriptor
    syscall

.exit:
    ; Exit the program
    xor edi, edi        ; exit code 0
    mov eax, 60         ; sys_exit
    syscall

; Function to check the file extension
check_extension:
    push rsi
    mov rdi, rsi        ; pointer to the file name
    mov rcx, rsi
    call strlen         ; get the length of the file name
    cmp rax, 4          ; minimum file name length for an extension
    jl .invalid_ext     ; if the name is too short, skip
    lea rdi, [rsi + rax - 4] ; pointer to the last 4 characters (extension)
    lea rsi, [txt_ext]  ; .txt extension
    call strcmp
    test rax, rax
    jz .valid_ext
    lea rsi, [jpg_ext]  ; .jpg extension
    call strcmp
    test rax, rax
    jz .valid_ext
.invalid_ext:
    xor rax, rax        ; extension doesn't match
    pop rsi
    ret
.valid_ext:
    mov rax, 1          ; extension matches
    pop rsi
    ret

; Function to compare strings
strcmp:
    mov rcx, 4          ; length of the extension
    xor rax, rax
.loop:
    mov dl, [rdi + rax]
    cmp dl, [rsi + rax]
    jne .not_equal
    inc rax
    loop .loop
    xor rax, rax        ; strings are equal
    ret
.not_equal:
    mov rax, 1          ; strings are not equal
    ret

; Function to calculate the length of a string
strlen:
    xor rax, rax
.loop:
    cmp byte [rcx + rax], 0
    je .done
    inc rax
    jmp .loop
.done:
    ret

segment readable writeable

dir_path db '.', 0      ; current directory path
dir_fd dd 0             ; directory file descriptor
dir_buf rb 1024         ; buffer for directory entries
newline db 10           ; newline character
txt_ext db '.txt', 0    ; .txt extension
jpg_ext db '.jpg', 0    ; .jpg extension    
You need to keep a closer look at the values used in the registers. Especially before and after subroutine calls
Post 26 Dec 2024, 19:10
View user's profile Send private message Reply with quote
alphv



Joined: 26 Dec 2024
Posts: 5
alphv 26 Dec 2024, 19:34
Thanks, bro. It helped a lot, now I understand better.

macomics wrote:
and more...
Code:
format ELF64 executable 3

segment readable executable

entry $

    ; Open the current directory
    mov eax, 2          ; sys_open
    lea rdi, [dir_path] ; path to the current directory
    mov rsi, 0          ; flags (O_RDONLY)
    mov rdx, 0          ; mode (not used)
    syscall

    cmp eax, 0          ; check if the directory was opened successfully
    jl .exit            ; if not, exit

    mov [dir_fd], eax   ; save the directory file descriptor

.read_dir:
    ; Read the next directory entry
    mov eax, 78         ; sys_getdents64
    mov edi, [dir_fd]   ; directory file descriptor
    lea rsi, [dir_buf]  ; buffer for reading
    mov rdx, 1024       ; buffer size
    syscall

    cmp eax, 0          ; check if the read was successful
    jle .close_dir      ; if not, close the directory

    ; Process the read data
    lea rbx, [dir_buf]  ; start of the buffer
    lea r8, [rax+rbx]        ; end of the buffer

.process_entry:
    ; Get the file name
    lea rsi, [rbx + 18] ; d_name in the linux_dirent64 structure

    ; Skip entries "." and ".."
    cmp byte [rsi], '.'
    je .next_entry

    ; Check the file extension
    call check_extension
    test rax, rax
    jz .next_entry      ; if the extension doesn't match, skip the file

    ; Print the file name with a new line
    mov rcx, rsi        ; pointer to the file name
    call strlen         ; get the length of the file name
    mov rdx, rax        ; length of the file name
    mov rdi, 1          ; STDOUT
    mov eax, 1          ; sys_write
    syscall

    ; Print a newline character
    mov eax, 1          ; sys_write
    mov rdi, 1          ; STDOUT
    lea rsi, [newline]  ; newline character
    mov rdx, 1          ; length of the newline character
    syscall

.next_entry:
    ; Move to the next entry
    movzx rdx, word [rbx + 16] ; d_reclen (record length)
    add rbx, rdx        ; move to the next record
    cmp rbx, r8        ; check if we reached the end of the buffer
    jl .process_entry   ; if not, continue processing

    jmp .read_dir       ; read the next chunk of data

.close_dir:
    ; Close the directory
    mov eax, 3          ; sys_close
    mov edi, [dir_fd]   ; directory file descriptor
    syscall

.exit:
    ; Exit the program
    xor edi, edi        ; exit code 0
    mov eax, 60         ; sys_exit
    syscall

; Function to check the file extension
check_extension:
    push rsi
    mov rdi, rsi        ; pointer to the file name
    mov rcx, rsi
    call strlen         ; get the length of the file name
    cmp rax, 4          ; minimum file name length for an extension
    jl .invalid_ext     ; if the name is too short, skip
    lea rdi, [rsi + rax - 4] ; pointer to the last 4 characters (extension)
    lea rsi, [txt_ext]  ; .txt extension
    call strcmp
    test rax, rax
    jz .valid_ext
    lea rsi, [jpg_ext]  ; .jpg extension
    call strcmp
    test rax, rax
    jz .valid_ext
.invalid_ext:
    xor rax, rax        ; extension doesn't match
    pop rsi
    ret
.valid_ext:
    mov rax, 1          ; extension matches
    pop rsi
    ret

; Function to compare strings
strcmp:
    mov rcx, 4          ; length of the extension
    xor rax, rax
.loop:
    mov dl, [rdi + rax]
    cmp dl, [rsi + rax]
    jne .not_equal
    inc rax
    loop .loop
    xor rax, rax        ; strings are equal
    ret
.not_equal:
    mov rax, 1          ; strings are not equal
    ret

; Function to calculate the length of a string
strlen:
    xor rax, rax
.loop:
    cmp byte [rcx + rax], 0
    je .done
    inc rax
    jmp .loop
.done:
    ret

segment readable writeable

dir_path db '.', 0      ; current directory path
dir_fd dd 0             ; directory file descriptor
dir_buf rb 1024         ; buffer for directory entries
newline db 10           ; newline character
txt_ext db '.txt', 0    ; .txt extension
jpg_ext db '.jpg', 0    ; .jpg extension    
You need to keep a closer look at the values used in the registers. Especially before and after subroutine calls
Post 26 Dec 2024, 19:34
View user's profile Send private message Reply with quote
alphv



Joined: 26 Dec 2024
Posts: 5
alphv 26 Dec 2024, 20:27
x86? Segmentation fault (core dumped)... Fix error, please

Code:
format ELF executable 3

segment readable executable

entry $

    ; Открываем текущий каталог
    mov eax, 5          ; sys_open
    mov ebx, dir_path   ; путь к текущему каталогу
    mov ecx, 0          ; флаги (O_RDONLY)
    mov edx, 0          ; режим (не используется)
    int 0x80

    cmp eax, 0          ; проверяем, успешно ли открыт каталог
    jl .exit            ; если нет, выходим

    mov [dir_fd], eax   ; сохраняем файловый дескриптор каталога

    ; Выводим сообщение об успешном открытии каталога
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_open   ; сообщение
    mov edx, msg_open_len ; длина сообщения
    int 0x80

.read_dir:
    ; Читаем следующую запись из каталога
    mov eax, 141        ; sys_getdents
    mov ebx, [dir_fd]   ; файловый дескриптор каталога
    mov ecx, dir_buf    ; буфер для чтения
    mov edx, 1024       ; размер буфера
    int 0x80

    cmp eax, 0          ; проверяем, успешно ли выполнено чтение
    jle .close_dir      ; если нет, закрываем каталог

    ; Выводим сообщение об успешном чтении
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_read   ; сообщение
    mov edx, msg_read_len ; длина сообщения
    int 0x80

    ; Обрабатываем прочитанные данные
    mov ebx, dir_buf    ; начало буфера
    lea edi, [ebx + eax] ; конец буфера

.process_entry:
    ; Получаем имя файла
    lea esi, [ebx + 10] ; d_name в структуре linux_dirent

    ; Пропускаем записи "." и ".."
    cmp byte [esi], '.'
    je .next_entry

    ; Проверяем расширение файла
    call check_extension
    test eax, eax
    jz .next_entry      ; если расширение не совпадает, пропускаем файл

    ; Выводим имя файла с новой строкой
    mov ecx, esi        ; указатель на имя файла
    call strlen         ; получаем длину имени файла
    mov edx, eax        ; длина имени файла
    mov ebx, 1          ; STDOUT
    mov eax, 4          ; sys_write
    int 0x80

    ; Выводим символ новой строки
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, newline    ; символ новой строки
    mov edx, 1          ; длина символа новой строки
    int 0x80

.next_entry:
    ; Переходим к следующей записи
    movzx edx, word [ebx + 8] ; d_reclen (длина записи)
    add ebx, edx        ; переходим к следующей записи
    cmp ebx, edi        ; проверяем, достигли ли конца буфера
    jl .process_entry   ; если нет, продолжаем обработку

    jmp .read_dir       ; читаем следующий блок данных

.close_dir:
    ; Закрываем каталог
    mov eax, 6          ; sys_close
    mov ebx, [dir_fd]   ; файловый дескриптор каталога
    int 0x80

    ; Проверяем, успешно ли закрыт каталог
    cmp eax, 0
    jl .close_error     ; если ошибка, выводим сообщение

    ; Выводим сообщение о закрытии каталога
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_close  ; сообщение
    mov edx, msg_close_len ; длина сообщения
    int 0x80
    jmp .exit

.close_error:
    ; Выводим сообщение об ошибке закрытия каталога
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_close_error ; сообщение
    mov edx, msg_close_error_len ; длина сообщения
    int 0x80

.exit:
    ; Завершаем программу
    xor ebx, ebx        ; код завершения 0
    mov eax, 1          ; sys_exit
    int 0x80

; Функция для проверки расширения файла
check_extension:
    push esi
    mov edi, esi        ; указатель на имя файла
    mov ecx, esi
    call strlen         ; получаем длину имени файла
    cmp eax, 4          ; минимальная длина имени файла для расширения
    jl .invalid_ext     ; если имя слишком короткое, пропускаем
    lea edi, [esi + eax - 4] ; указатель на последние 4 символа (расширение)
    mov esi, txt_ext    ; расширение .txt
    call strcmp
    test eax, eax
    jz .valid_ext
    mov esi, jpg_ext    ; расширение .jpg
    call strcmp
    test eax, eax
    jz .valid_ext
.invalid_ext:
    xor eax, eax        ; расширение не совпадает
    pop esi
    ret
.valid_ext:
    mov eax, 1          ; расширение совпадает
    pop esi
    ret

; Функция для сравнения строк
strcmp:
    mov ecx, 4          ; длина расширения
    xor eax, eax
.loop:
    mov dl, [edi + eax]
    cmp dl, [esi + eax]
    jne .not_equal
    inc eax
    loop .loop
    xor eax, eax        ; строки равны
    ret
.not_equal:
    mov eax, 1          ; строки не равны
    ret

; Функция для вычисления длины строки
strlen:
    xor eax, eax
.loop:
    cmp byte [ecx + eax], 0
    je .done
    inc eax
    jmp .loop
.done:
    ret

segment readable writeable

dir_path db '.', 0      ; путь к текущему каталогу
dir_fd dd 0             ; файловый дескриптор каталога
dir_buf rb 1024         ; буфер для записей каталога
newline db 10           ; символ новой строки
txt_ext db '.txt', 0    ; расширение .txt
jpg_ext db '.jpg', 0    ; расширение .jpg

msg_open db 'dir_open.', 10
msg_open_len = $ - msg_open

msg_read db 'dir_read.', 10
msg_read_len = $ - msg_read

msg_close db 'dir_closed.', 10
msg_close_len = $ - msg_close

msg_close_error db 'error.', 10
msg_close_error_len = $ - msg_close_error    
[/code]
Post 26 Dec 2024, 20:27
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1041
Location: Russia
macomics 26 Dec 2024, 21:22
Code:
format ELF executable 3

segment readable executable

entry $

    ; Открываем текущий каталог
    mov eax, 5          ; sys_open
    mov ebx, dir_path   ; путь к текущему каталогу
    mov ecx, 0          ; флаги (O_RDONLY)
    mov edx, 0          ; режим (не используется)
    int 0x80

    cmp eax, 0          ; проверяем, успешно ли открыт каталог
    jl .exit            ; если нет, выходим

    mov [dir_fd], eax   ; сохраняем файловый дескриптор каталога

    ; Выводим сообщение об успешном открытии каталога
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_open   ; сообщение
    mov edx, msg_open_len ; длина сообщения
    int 0x80

.read_dir:
    ; Читаем следующую запись из каталога
    mov eax, 141        ; sys_getdents
    mov ebx, [dir_fd]   ; файловый дескриптор каталога
    mov ecx, dir_buf    ; буфер для чтения
    mov edx, 1024       ; размер буфера
    int 0x80

    cmp eax, 0          ; проверяем, успешно ли выполнено чтение
    jle .close_dir      ; если нет, закрываем каталог
    lea edi, [ecx + eax] ; конец буфера

; Вот это у вас изменит eax...
    ; Выводим сообщение об успешном чтении
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_read   ; сообщение
    mov edx, msg_read_len ; длина сообщения
    int 0x80

; ...поэтому тут в eax уже будет не длина прочитанных в буфер байт
; поэтому сохраняем это значение в edi сразу
    ; Обрабатываем прочитанные данные
    mov ebx, dir_buf    ; начало буфера

.process_entry:
    ; Получаем имя файла
    lea esi, [ebx + 10] ; d_name в структуре linux_dirent

    ; Пропускаем записи "." и ".."
    cmp byte [esi], '.'
    je .next_entry

    ; Проверяем расширение файла
    call check_extension
    test eax, eax
    jz .next_entry      ; если расширение не совпадает, пропускаем файл

    ; Следующие вызовы разрушают значения в ebx...
    push ebx
    ; Выводим имя файла с новой строкой
    mov ecx, esi        ; указатель на имя файла
    call strlen         ; получаем длину имени файла
    mov edx, eax        ; длина имени файла
    mov ebx, 1          ; STDOUT
    mov eax, 4          ; sys_write
    int 0x80

    ; Выводим символ новой строки
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, newline    ; символ новой строки
    mov edx, 1          ; длина символа новой строки
    int 0x80
    pop ebx

.next_entry: ; ...которое необходимо тут!
    ; Переходим к следующей записи
    movzx eax, word [ebx + 8] ; d_reclen (длина записи)
    add ebx, eax        ; переходим к следующей записи
    cmp ebx, edi        ; проверяем, достигли ли конца буфера
    jl .process_entry   ; если нет, продолжаем обработку

    jmp .read_dir       ; читаем следующий блок данных

.close_dir:
    ; Закрываем каталог
    mov eax, 6          ; sys_close
    mov ebx, [dir_fd]   ; файловый дескриптор каталога
    int 0x80

    ; Проверяем, успешно ли закрыт каталог
    cmp eax, 0
    jl .close_error     ; если ошибка, выводим сообщение

    ; Выводим сообщение о закрытии каталога
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_close  ; сообщение
    mov edx, msg_close_len ; длина сообщения
    int 0x80
    jmp .exit

.close_error:
    ; Выводим сообщение об ошибке закрытия каталога
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_close_error ; сообщение
    mov edx, msg_close_error_len ; длина сообщения
    int 0x80

.exit:
    ; Завершаем программу
    xor ebx, ebx        ; код завершения 0
    mov eax, 1          ; sys_exit
    int 0x80

; Функция для проверки расширения файла
check_extension:
; теперь надо сохранять и edi
    push edi
    push esi
    mov edi, esi        ; указатель на имя файла
    mov ecx, esi
    call strlen         ; получаем длину имени файла
    cmp eax, 4          ; минимальная длина имени файла для расширения
    jl .invalid_ext     ; если имя слишком короткое, пропускаем
    lea edi, [esi + eax - 4] ; указатель на последние 4 символа (расширение)
    mov esi, txt_ext    ; расширение .txt
    call strcmp
    test eax, eax
    jz .valid_ext
    mov esi, jpg_ext    ; расширение .jpg
    call strcmp
    test eax, eax
    jz .valid_ext
.invalid_ext:
    xor eax, eax        ; расширение не совпадает
    pop esi
    pop edi
    ret
.valid_ext:
    mov eax, 1          ; расширение совпадает
    pop esi
    pop edi
    ret

; Функция для сравнения строк
strcmp:
    mov ecx, 4          ; длина расширения
    xor eax, eax
.loop:
    mov dl, [edi + eax]
    cmp dl, [esi + eax]
    jne .not_equal
    inc eax
    loop .loop
    xor eax, eax        ; строки равны
    ret
.not_equal:
    mov eax, 1          ; строки не равны
    ret

; Функция для вычисления длины строки
strlen:
    xor eax, eax
.loop:
    cmp byte [ecx + eax], 0
    je .done
    inc eax
    jmp .loop
.done:
    ret

segment readable writeable

dir_path db '.', 0      ; путь к текущему каталогу
dir_fd dd 0             ; файловый дескриптор каталога
dir_buf rb 1024         ; буфер для записей каталога
newline db 10           ; символ новой строки
txt_ext db '.txt', 0    ; расширение .txt
jpg_ext db '.jpg', 0    ; расширение .jpg

msg_open db 'dir_open.', 10
msg_open_len = $ - msg_open

msg_read db 'dir_read.', 10
msg_read_len = $ - msg_read

msg_close db 'dir_closed.', 10
msg_close_len = $ - msg_close

msg_close_error db 'error.', 10
msg_close_error_len = $ - msg_close_error
    
Post 26 Dec 2024, 21:22
View user's profile Send private message Reply with quote
alphv



Joined: 26 Dec 2024
Posts: 5
alphv 26 Dec 2024, 21:26
Thanks again)

macomics wrote:
Code:
format ELF executable 3

segment readable executable

entry $

    ; Открываем текущий каталог
    mov eax, 5          ; sys_open
    mov ebx, dir_path   ; путь к текущему каталогу
    mov ecx, 0          ; флаги (O_RDONLY)
    mov edx, 0          ; режим (не используется)
    int 0x80

    cmp eax, 0          ; проверяем, успешно ли открыт каталог
    jl .exit            ; если нет, выходим

    mov [dir_fd], eax   ; сохраняем файловый дескриптор каталога

    ; Выводим сообщение об успешном открытии каталога
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_open   ; сообщение
    mov edx, msg_open_len ; длина сообщения
    int 0x80

.read_dir:
    ; Читаем следующую запись из каталога
    mov eax, 141        ; sys_getdents
    mov ebx, [dir_fd]   ; файловый дескриптор каталога
    mov ecx, dir_buf    ; буфер для чтения
    mov edx, 1024       ; размер буфера
    int 0x80

    cmp eax, 0          ; проверяем, успешно ли выполнено чтение
    jle .close_dir      ; если нет, закрываем каталог
    lea edi, [ecx + eax] ; конец буфера

; Вот это у вас изменит eax...
    ; Выводим сообщение об успешном чтении
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_read   ; сообщение
    mov edx, msg_read_len ; длина сообщения
    int 0x80

; ...поэтому тут в eax уже будет не длина прочитанных в буфер байт
; поэтому сохраняем это значение в edi сразу
    ; Обрабатываем прочитанные данные
    mov ebx, dir_buf    ; начало буфера

.process_entry:
    ; Получаем имя файла
    lea esi, [ebx + 10] ; d_name в структуре linux_dirent

    ; Пропускаем записи "." и ".."
    cmp byte [esi], '.'
    je .next_entry

    ; Проверяем расширение файла
    call check_extension
    test eax, eax
    jz .next_entry      ; если расширение не совпадает, пропускаем файл

    ; Следующие вызовы разрушают значения в ebx...
    push ebx
    ; Выводим имя файла с новой строкой
    mov ecx, esi        ; указатель на имя файла
    call strlen         ; получаем длину имени файла
    mov edx, eax        ; длина имени файла
    mov ebx, 1          ; STDOUT
    mov eax, 4          ; sys_write
    int 0x80

    ; Выводим символ новой строки
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, newline    ; символ новой строки
    mov edx, 1          ; длина символа новой строки
    int 0x80
    pop ebx

.next_entry: ; ...которое необходимо тут!
    ; Переходим к следующей записи
    movzx eax, word [ebx + 8] ; d_reclen (длина записи)
    add ebx, eax        ; переходим к следующей записи
    cmp ebx, edi        ; проверяем, достигли ли конца буфера
    jl .process_entry   ; если нет, продолжаем обработку

    jmp .read_dir       ; читаем следующий блок данных

.close_dir:
    ; Закрываем каталог
    mov eax, 6          ; sys_close
    mov ebx, [dir_fd]   ; файловый дескриптор каталога
    int 0x80

    ; Проверяем, успешно ли закрыт каталог
    cmp eax, 0
    jl .close_error     ; если ошибка, выводим сообщение

    ; Выводим сообщение о закрытии каталога
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_close  ; сообщение
    mov edx, msg_close_len ; длина сообщения
    int 0x80
    jmp .exit

.close_error:
    ; Выводим сообщение об ошибке закрытия каталога
    mov eax, 4          ; sys_write
    mov ebx, 1          ; STDOUT
    mov ecx, msg_close_error ; сообщение
    mov edx, msg_close_error_len ; длина сообщения
    int 0x80

.exit:
    ; Завершаем программу
    xor ebx, ebx        ; код завершения 0
    mov eax, 1          ; sys_exit
    int 0x80

; Функция для проверки расширения файла
check_extension:
; теперь надо сохранять и edi
    push edi
    push esi
    mov edi, esi        ; указатель на имя файла
    mov ecx, esi
    call strlen         ; получаем длину имени файла
    cmp eax, 4          ; минимальная длина имени файла для расширения
    jl .invalid_ext     ; если имя слишком короткое, пропускаем
    lea edi, [esi + eax - 4] ; указатель на последние 4 символа (расширение)
    mov esi, txt_ext    ; расширение .txt
    call strcmp
    test eax, eax
    jz .valid_ext
    mov esi, jpg_ext    ; расширение .jpg
    call strcmp
    test eax, eax
    jz .valid_ext
.invalid_ext:
    xor eax, eax        ; расширение не совпадает
    pop esi
    pop edi
    ret
.valid_ext:
    mov eax, 1          ; расширение совпадает
    pop esi
    pop edi
    ret

; Функция для сравнения строк
strcmp:
    mov ecx, 4          ; длина расширения
    xor eax, eax
.loop:
    mov dl, [edi + eax]
    cmp dl, [esi + eax]
    jne .not_equal
    inc eax
    loop .loop
    xor eax, eax        ; строки равны
    ret
.not_equal:
    mov eax, 1          ; строки не равны
    ret

; Функция для вычисления длины строки
strlen:
    xor eax, eax
.loop:
    cmp byte [ecx + eax], 0
    je .done
    inc eax
    jmp .loop
.done:
    ret

segment readable writeable

dir_path db '.', 0      ; путь к текущему каталогу
dir_fd dd 0             ; файловый дескриптор каталога
dir_buf rb 1024         ; буфер для записей каталога
newline db 10           ; символ новой строки
txt_ext db '.txt', 0    ; расширение .txt
jpg_ext db '.jpg', 0    ; расширение .jpg

msg_open db 'dir_open.', 10
msg_open_len = $ - msg_open

msg_read db 'dir_read.', 10
msg_read_len = $ - msg_read

msg_close db 'dir_closed.', 10
msg_close_len = $ - msg_close

msg_close_error db 'error.', 10
msg_close_error_len = $ - msg_close_error
    
Post 26 Dec 2024, 21:26
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.