141 lines
4 KiB
NASM
141 lines
4 KiB
NASM
; ----------------------------------------------------------
|
|
; Arquivo : salve-pipe.asm
|
|
; Reproduz: echo 'Salve, simpatia!' | cat
|
|
; Montagem: nasm -f elf64 salve-pipe.asm
|
|
; Ligação : ld -o salve-pipe salve-pipe.o
|
|
; ----------------------------------------------------------
|
|
; Chamadas de sistema...
|
|
; ----------------------------------------------------------
|
|
%define SYS_WRITE 1
|
|
%define SYS_CLOSE 3
|
|
%define SYS_PIPE 22
|
|
%define SYS_DUP2 33
|
|
%define SYS_FORK 57
|
|
%define SYS_EXECVE 59
|
|
%define SYS_EXIT 60
|
|
%define SYS_WAIT 61
|
|
; ----------------------------------------------------------
|
|
; Parâmetros de SYS_WAIT...
|
|
; ----------------------------------------------------------
|
|
%define W_CHILD -1 ; filho de qualquer PID
|
|
%define W_STATUS 0 ; ignorar o estado de término (NULL)
|
|
%define W_OPTIONS 0 ; sem opções
|
|
; ----------------------------------------------------------
|
|
; Descritores de arquivos padrão...
|
|
; ----------------------------------------------------------
|
|
%define STDIN_FD 0
|
|
%define STDOUT_FD 1
|
|
; ----------------------------------------------------------
|
|
; Estados de término...
|
|
; ----------------------------------------------------------
|
|
%define EXIT_SUCCESS 0
|
|
%define EXIT_ERROR 1
|
|
; ----------------------------------------------------------
|
|
section .rodata
|
|
; ----------------------------------------------------------
|
|
; Mensagem...
|
|
msg db "Salve, simpatia!", 10
|
|
len equ $ - msg
|
|
|
|
; Argumentos de execve...
|
|
comm db "/bin/cat", 0
|
|
argv dq comm, 0
|
|
envp dq 0
|
|
; ----------------------------------------------------------
|
|
section .bss
|
|
; ----------------------------------------------------------
|
|
read_end resd 1 ; Descritor da ponta de leitura do pipe
|
|
write_end resd 1 ; Descritor da ponta de escrita do pipe
|
|
; ----------------------------------------------------------
|
|
section .text
|
|
; ----------------------------------------------------------
|
|
global _start
|
|
|
|
_start:
|
|
; pipe(int pipefd[])
|
|
; retorna: pipefd[0] => read_end; pipefd[1] => write_end
|
|
mov rax, SYS_PIPE
|
|
mov rdi, read_end ; Retorno vai avançar em write_end
|
|
syscall
|
|
|
|
.parada1: ; examinar FDs retornados!
|
|
|
|
; fork()
|
|
mov rax, SYS_FORK
|
|
syscall
|
|
|
|
test rax, rax ; rax = 0 -> processo filho
|
|
jz .filho ; pula a execução do código do pai
|
|
; ----------------------------------------------------------
|
|
; Código executado apenas no processo pai...
|
|
; ----------------------------------------------------------
|
|
.pai:
|
|
; ----------------------------------------------------------
|
|
; dup2(write_end, STDOUT)
|
|
mov rax, SYS_DUP2
|
|
mov edi, [write_end] ; FD original: write_end
|
|
mov rsi, STDOUT_FD ; novo descritor de escrita
|
|
syscall
|
|
|
|
; Fechar write_end e read_end...
|
|
call _close_all
|
|
|
|
.parada2: ;examinar /proc/<pid>/fd!
|
|
|
|
; write(STDOUT, msg, len)
|
|
mov rax, SYS_WRITE
|
|
mov rdi, STDOUT_FD
|
|
mov rsi, msg
|
|
mov rdx, len
|
|
syscall
|
|
|
|
; wait4(-1, NULL, 0)
|
|
mov rax, SYS_WAIT
|
|
mov rdi, W_CHILD
|
|
mov rsi, W_STATUS
|
|
mov rdx, W_OPTIONS
|
|
|
|
; exit(0)
|
|
mov rax, SYS_EXIT
|
|
mov rdi, EXIT_SUCCESS ; sai com sucesso se chegar aqui
|
|
syscall
|
|
; ----------------------------------------------------------
|
|
; Código executado apenas no processo filho...
|
|
; ----------------------------------------------------------
|
|
.filho:
|
|
; ----------------------------------------------------------
|
|
; dup2(read_end, STDIN)
|
|
mov rax, SYS_DUP2
|
|
mov edi, [read_end] ; descritor de leitura no pipe
|
|
mov rsi, STDIN_FD ; novo descritor de leitura
|
|
syscall
|
|
|
|
; Fechar write_end e read_end...
|
|
call _close_all
|
|
|
|
; execve("/bin/cat", ["/bin/cat", NULL], [NULL])
|
|
mov rax, SYS_EXECVE
|
|
mov rdi, comm
|
|
mov rsi, argv
|
|
mov rdx, envp
|
|
syscall
|
|
|
|
; exit(1)
|
|
mov rax, SYS_EXIT
|
|
mov rdi, EXIT_ERROR ; sai com erro se execve falhar
|
|
syscall
|
|
; ----------------------------------------------------------
|
|
; Sub de fechamento dos descritores originais do pipe...
|
|
; ----------------------------------------------------------
|
|
_close_all:
|
|
; ----------------------------------------------------------
|
|
; close(read_end)
|
|
mov rax, SYS_CLOSE
|
|
mov rdi, [read_end]
|
|
syscall
|
|
; close(write_end)
|
|
mov rax, SYS_CLOSE
|
|
mov rdi, [write_end]
|
|
syscall
|
|
ret
|
|
|