89 lines
4.1 KiB
NASM
89 lines
4.1 KiB
NASM
; ----------------------------------------------------------
|
|
; Montagem: nasm -f elf64 cgetenv.asm
|
|
; Ligação : gcc -no-pie -o cgetenv cgetenv.o
|
|
; Uso : ./cgetenv PATH
|
|
; ----------------------------------------------------------
|
|
; Funções importadas da glibc...
|
|
; ----------------------------------------------------------
|
|
extern getenv
|
|
extern puts
|
|
extern fprintf
|
|
extern exit
|
|
extern stderr
|
|
; ----------------------------------------------------------
|
|
section .rodata
|
|
; ----------------------------------------------------------
|
|
msg_nf db "Not found", 10, 0
|
|
msg_usage db "Usage: ./getenv VAR", 10, 0
|
|
; ----------------------------------------------------------
|
|
section .bss
|
|
; ----------------------------------------------------------
|
|
argc resq 1 ; recebe quantidade de argumentos
|
|
argv resq 1 ; recebe endereço de argv[0]
|
|
envp resq 1 ; recebe endereço de envp[0]
|
|
; ----------------------------------------------------------
|
|
section .text
|
|
; ----------------------------------------------------------
|
|
global main
|
|
main:
|
|
; ----------------------------------------------------------
|
|
; Iniciar quadro de pilha para main...
|
|
; ----------------------------------------------------------
|
|
push rbp
|
|
mov rbp, rsp
|
|
; ----------------------------------------------------------
|
|
; Salvar dados de argumentos e ambiente...
|
|
; ----------------------------------------------------------
|
|
mov [argc], rdi ; salvar valor de argc
|
|
mov [argv], rsi ; salvar endereço de argv[0]
|
|
mov [envp], rdx ; salvar endereço de envp[0]
|
|
; ----------------------------------------------------------
|
|
; Verificar se argc < 2
|
|
; ----------------------------------------------------------
|
|
cmp rdi, 2
|
|
jl show_usage
|
|
; ----------------------------------------------------------
|
|
; getenv(argv[1]);
|
|
; ----------------------------------------------------------
|
|
mov rax, [argv] ; endereço de argv[0]
|
|
mov rdi, [rax + 8] ; argumento 1: endereço de argv[1]
|
|
call getenv ; chamar getenv
|
|
test rax, rax ; testar retorno (0 = não encontrada)
|
|
jz not_found
|
|
; ----------------------------------------------------------
|
|
; Imprimir valor encontrado: puts(char *valor)
|
|
; ----------------------------------------------------------
|
|
mov rdi, rax ; argumento 1: endereço do valor em rax
|
|
call puts ; chamar puts
|
|
; ----------------------------------------------------------
|
|
; Término com sucesso: exit(int status);
|
|
; ----------------------------------------------------------
|
|
mov edi, 0 ; argumento 1: (int)0 - sucesso
|
|
call exit ; chamar exit
|
|
; ----------------------------------------------------------
|
|
; Se o nome da variável não for encontrado...
|
|
; ----------------------------------------------------------
|
|
not_found:
|
|
; ----------------------------------------------------------
|
|
; Mensagem de erro: fprintf(stderr, "Not found\n");
|
|
; ----------------------------------------------------------
|
|
mov rdi, [stderr] ; argumento 1: stream de saída
|
|
lea rsi, [msg_nf] ; argumento 2: string de formato
|
|
call fprintf ; chamar fprintf
|
|
jmp exit_error ; termina com erro
|
|
; ----------------------------------------------------------
|
|
; Quantidade de argumentos incorrerta...
|
|
; ----------------------------------------------------------
|
|
show_usage:
|
|
; ----------------------------------------------------------
|
|
; Mensagem de erro: fprintf(stderr, "Usage: ./getenv VAR\n");
|
|
; ----------------------------------------------------------
|
|
mov rdi, [stderr] ; argumento 1: stream de saída
|
|
lea rsi, [msg_usage] ; argumento 2: string de formato
|
|
call fprintf ; chamar fprintf
|
|
; ----------------------------------------------------------
|
|
; Término com erro
|
|
; ----------------------------------------------------------
|
|
exit_error:
|
|
mov edi, 1 ; argumento 1: (int)1 - erro
|
|
call exit ; chamar exit
|