pbn/curso/exemplos/07/cgetenv.asm
2025-05-26 08:04:03 -03:00

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