Exercício da Aula 15 #31

Open
opened 2025-08-04 21:48:59 -03:00 by leandrossantos · 0 comments

Arquivo mycat:

%include "mycatlib.asm"

section .rodata
    use_msg db "Uso: ./mycat <nome_do_arquivo>", 10, 0
    use_len equ $ - use_msg

    err_msg db "Erro: não foi possível abrir o arquivo", 10, 0
    err_len equ $ - err_msg

section .bss
    buf resb BUF_SIZE       ; buffer para leitura do arquivo

section .text
    global _start

_start:
    ; Verificando se foi passado um nome de arquivo como argumento
    pop rax                 ; argc agora está em rax
    cmp rax, 2              ; Tem 2 argumentos?
    je _save_arg            ; se sim, vá para _save_arg

    mov rdi, use_len        ; rdi recebe o tamanho da mensagem
    mov rsi, use_msg        ; rsi recebe o endereço da mensagem
    call die                ; se não, termina com erro

_save_arg:
    ; Salvando argv[1] em rdi
    pop rax                 ; endereço de argv[0] agora está em rax
    pop rdi                 ; endereço de argv[1] agora está em rdi
    
    call open_file          ; syscall open para abrir o arquivo
    cmp rax, 0              ; o arquivo foi aberto com sucesso?
    jge _save_fd            ; se sim, vá para _save_fd

    mov rdi, err_len        ; rdi recebe o tamanho da mensagem
    mov rsi, err_msg        ; rsi recebe o endereço da mensagem
    call die                ; se não, termina com erro

_save_fd:
    mov rdi, rax            ; rdi recebe o descritor do arquivo
    mov rsi, buf            ; rsi recebe o endereço do buffer
    call read_loop          ; inicia a leitura do arquivo
    call close_file         ; Fecha o arquivo (rdi ainda contém o fd)
    call exit_ok            ; termina com sucesso

Arquivo mycatlib.asm:

%ifndef MY_CATLIB
%define MY_CATLIB
;----------------------------------------------------
%define SYS_READ    0
%define SYS_WRITE   1
%define SYS_OPEN    2
%define SYS_CLOSE   3
%define SYS_EXIT    60
;----------------------------------------------------
%define STDOUT      1
%define STDERR      2
;----------------------------------------------------
%define EXIT_OK     0
%define EXIT_ERROR  1
;----------------------------------------------------
%define BUF_SIZE    8192 
;----------------------------------------------------
%define O_RDONLY    0
;----------------------------------------------------


;----------------------------------------------------
; Lê e imprime as linhas do arquivo
;----------------------------------------------------
; rdi <- descritor de arquivos
; rsi <- endereço do buffer
;----------------------------------------------------
; Altera: rax, rcx, rdx, rdi, r11
;----------------------------------------------------
; Depende: close_file
;----------------------------------------------------
read_loop:
    ; Lendo o arquivo
    mov rax, SYS_READ       ; syscall read
    mov rdx, BUF_SIZE       ; quantidade de bytes para leitura
    syscall

    ; Verificando se chegamos ao fim do arquivo
    cmp rax, 0              ; rax <= 0?
    jle .return             ; se sim, retorna

.print_line:
    push rdi                ; salva rdi na pilha

    ; Escrevendo a leitura do arquivo na saída padrão (STDOUT)
    mov rdx, rax            ; quantidade de bytes lidos
    mov rax, SYS_WRITE      ; syscall write
    mov rdi, STDOUT         ; saída padrão
    syscall

    pop rdi                 ; restaura o valor de rdi

    jmp read_loop

.return:
    ret

;----------------------------------------------------
; Fecha o arquivo
;----------------------------------------------------
; rdi <- descritor de arquivos
;----------------------------------------------------
; Altera: rax, rcx, r11
;----------------------------------------------------
close_file:
    ; Fechando o arquivo
    mov rax, SYS_CLOSE      ; syscall close
    syscall

    ret

;----------------------------------------------------
; Imprime a mensagem de erro e sai 
;----------------------------------------------------
; rdi <- tamanho da mensagem
; rsi <- endereço da mensagem
;----------------------------------------------------
; Altera: rax, rcx, r11, rdi, 
;----------------------------------------------------
die:
    ; Mostrando mensagem de uso correto
    mov rdx, rdi            ; tamanho da mensagem
    mov rax, SYS_WRITE      ; syscall write
    mov rdi, STDERR         ; saída de erro padrão (STDERR)
    syscall

    call exit_error

    ret

;----------------------------------------------------
; Abre o arquivo 
;----------------------------------------------------
; rdi <- caminho do arquivo
;----------------------------------------------------
; rax <- descritor de arquivo retornado
;----------------------------------------------------
; Altera: rax, rcx, r11 
;----------------------------------------------------
open_file:
    ; Abrindo o arquivo (rdi já aponta para o nome do arquivo)
    mov rax, SYS_OPEN       ; syscall open
    mov rsi, O_RDONLY       ; flag somente leitura
    mov rdx, 0              ; usado apenas quando um novo arquivo é criado
    syscall

    ret

;----------------------------------------------------
; Termina com sucesso
;----------------------------------------------------
exit_ok:    
    ; Saindo com sucesso (código de término 0)
    mov rax, SYS_EXIT       ; syscall exit
    mov rdi, EXIT_OK        ; rdi = 0
    syscall

;----------------------------------------------------
; Termina com erro 
;----------------------------------------------------
exit_error:
    ; Saindo com código de erro 1
    mov rax, SYS_EXIT       ; syscall exit
    mov rdi, EXIT_ERROR     ; código de erro 1
    syscall

%endif
Arquivo mycat: ```asm %include "mycatlib.asm" section .rodata use_msg db "Uso: ./mycat <nome_do_arquivo>", 10, 0 use_len equ $ - use_msg err_msg db "Erro: não foi possível abrir o arquivo", 10, 0 err_len equ $ - err_msg section .bss buf resb BUF_SIZE ; buffer para leitura do arquivo section .text global _start _start: ; Verificando se foi passado um nome de arquivo como argumento pop rax ; argc agora está em rax cmp rax, 2 ; Tem 2 argumentos? je _save_arg ; se sim, vá para _save_arg mov rdi, use_len ; rdi recebe o tamanho da mensagem mov rsi, use_msg ; rsi recebe o endereço da mensagem call die ; se não, termina com erro _save_arg: ; Salvando argv[1] em rdi pop rax ; endereço de argv[0] agora está em rax pop rdi ; endereço de argv[1] agora está em rdi call open_file ; syscall open para abrir o arquivo cmp rax, 0 ; o arquivo foi aberto com sucesso? jge _save_fd ; se sim, vá para _save_fd mov rdi, err_len ; rdi recebe o tamanho da mensagem mov rsi, err_msg ; rsi recebe o endereço da mensagem call die ; se não, termina com erro _save_fd: mov rdi, rax ; rdi recebe o descritor do arquivo mov rsi, buf ; rsi recebe o endereço do buffer call read_loop ; inicia a leitura do arquivo call close_file ; Fecha o arquivo (rdi ainda contém o fd) call exit_ok ; termina com sucesso ``` Arquivo mycatlib.asm: ```asm %ifndef MY_CATLIB %define MY_CATLIB ;---------------------------------------------------- %define SYS_READ 0 %define SYS_WRITE 1 %define SYS_OPEN 2 %define SYS_CLOSE 3 %define SYS_EXIT 60 ;---------------------------------------------------- %define STDOUT 1 %define STDERR 2 ;---------------------------------------------------- %define EXIT_OK 0 %define EXIT_ERROR 1 ;---------------------------------------------------- %define BUF_SIZE 8192 ;---------------------------------------------------- %define O_RDONLY 0 ;---------------------------------------------------- ;---------------------------------------------------- ; Lê e imprime as linhas do arquivo ;---------------------------------------------------- ; rdi <- descritor de arquivos ; rsi <- endereço do buffer ;---------------------------------------------------- ; Altera: rax, rcx, rdx, rdi, r11 ;---------------------------------------------------- ; Depende: close_file ;---------------------------------------------------- read_loop: ; Lendo o arquivo mov rax, SYS_READ ; syscall read mov rdx, BUF_SIZE ; quantidade de bytes para leitura syscall ; Verificando se chegamos ao fim do arquivo cmp rax, 0 ; rax <= 0? jle .return ; se sim, retorna .print_line: push rdi ; salva rdi na pilha ; Escrevendo a leitura do arquivo na saída padrão (STDOUT) mov rdx, rax ; quantidade de bytes lidos mov rax, SYS_WRITE ; syscall write mov rdi, STDOUT ; saída padrão syscall pop rdi ; restaura o valor de rdi jmp read_loop .return: ret ;---------------------------------------------------- ; Fecha o arquivo ;---------------------------------------------------- ; rdi <- descritor de arquivos ;---------------------------------------------------- ; Altera: rax, rcx, r11 ;---------------------------------------------------- close_file: ; Fechando o arquivo mov rax, SYS_CLOSE ; syscall close syscall ret ;---------------------------------------------------- ; Imprime a mensagem de erro e sai ;---------------------------------------------------- ; rdi <- tamanho da mensagem ; rsi <- endereço da mensagem ;---------------------------------------------------- ; Altera: rax, rcx, r11, rdi, ;---------------------------------------------------- die: ; Mostrando mensagem de uso correto mov rdx, rdi ; tamanho da mensagem mov rax, SYS_WRITE ; syscall write mov rdi, STDERR ; saída de erro padrão (STDERR) syscall call exit_error ret ;---------------------------------------------------- ; Abre o arquivo ;---------------------------------------------------- ; rdi <- caminho do arquivo ;---------------------------------------------------- ; rax <- descritor de arquivo retornado ;---------------------------------------------------- ; Altera: rax, rcx, r11 ;---------------------------------------------------- open_file: ; Abrindo o arquivo (rdi já aponta para o nome do arquivo) mov rax, SYS_OPEN ; syscall open mov rsi, O_RDONLY ; flag somente leitura mov rdx, 0 ; usado apenas quando um novo arquivo é criado syscall ret ;---------------------------------------------------- ; Termina com sucesso ;---------------------------------------------------- exit_ok: ; Saindo com sucesso (código de término 0) mov rax, SYS_EXIT ; syscall exit mov rdi, EXIT_OK ; rdi = 0 syscall ;---------------------------------------------------- ; Termina com erro ;---------------------------------------------------- exit_error: ; Saindo com código de erro 1 mov rax, SYS_EXIT ; syscall exit mov rdi, EXIT_ERROR ; código de erro 1 syscall %endif ```
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: blau_araujo/pbn#31
No description provided.