exemplos da aula 6
This commit is contained in:
parent
ee62511898
commit
4d701d4461
5 changed files with 304 additions and 0 deletions
66
curso/exemplos/06/args.asm
Normal file
66
curso/exemplos/06/args.asm
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
; ----------------------------------------------------------
|
||||||
|
; Arquivo : args.asm
|
||||||
|
; Descrição : Imprime argc e argv[0 .. (argc-1)]
|
||||||
|
; Montar com: nasm -f elf64 args.asm
|
||||||
|
; Ligar com : ls -o args args.o print_utils.o
|
||||||
|
; ----------------------------------------------------------
|
||||||
|
section .rodata
|
||||||
|
pref_argc db "argc : ", 0
|
||||||
|
pref_argv db "argv[", 0
|
||||||
|
posf_argv db "]: ", 0
|
||||||
|
|
||||||
|
; sub-rotinas do módulo print_utils.o
|
||||||
|
extern print_int
|
||||||
|
extern print_str
|
||||||
|
extern print_char
|
||||||
|
|
||||||
|
section .text
|
||||||
|
global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
; ----------------------------------------------------------
|
||||||
|
; Impressão de argc
|
||||||
|
; ----------------------------------------------------------
|
||||||
|
mov rdi, pref_argc ; endereço de pref_argc
|
||||||
|
call print_str ; imprime pref_argc
|
||||||
|
|
||||||
|
mov rax, [rsp] ; rax = argc
|
||||||
|
call print_int ; imprime argc
|
||||||
|
|
||||||
|
mov rdi, 10 ; rdi = \n
|
||||||
|
call print_char ; imprime \n
|
||||||
|
; ----------------------------------------------------------
|
||||||
|
; Impressão de argv
|
||||||
|
; ----------------------------------------------------------
|
||||||
|
mov rcx, 0 ; índice i = 0
|
||||||
|
lea rbx, [rsp + 8] ; rbx = endereço de argv[0]
|
||||||
|
|
||||||
|
.print_argv_loop:
|
||||||
|
cmp rcx, [rsp] ; enquanto i < argc
|
||||||
|
jge .done_argv
|
||||||
|
|
||||||
|
mov rdi, pref_argv ; imprime prefixo "argv["
|
||||||
|
call print_str
|
||||||
|
|
||||||
|
mov rax, rcx ; rax = i
|
||||||
|
call print_int ; imprime índice
|
||||||
|
|
||||||
|
mov rdi, posf_argv ; imprime sufixo "]: "
|
||||||
|
call print_str
|
||||||
|
|
||||||
|
mov rdi, [rbx + rcx*8] ; rdi = argv[i]
|
||||||
|
call print_str
|
||||||
|
|
||||||
|
mov rdi, 10 ; imprime \n
|
||||||
|
call print_char
|
||||||
|
|
||||||
|
inc rcx
|
||||||
|
jmp .print_argv_loop
|
||||||
|
|
||||||
|
.done_argv:
|
||||||
|
; ----------------------------------------------------------
|
||||||
|
; Termina o programa com exit(0)
|
||||||
|
; ----------------------------------------------------------
|
||||||
|
mov rax, 60 ; syscall: exit
|
||||||
|
xor rdi, rdi ; status = 0
|
||||||
|
syscall
|
50
curso/exemplos/06/cargs.asm
Normal file
50
curso/exemplos/06/cargs.asm
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
section .bss
|
||||||
|
argc: resq 1 ; 8 bytes para armazenar argc
|
||||||
|
argv: resq 1 ; 8 bytes para armazenar ponteiro para argv[0]
|
||||||
|
|
||||||
|
section .data
|
||||||
|
fmt_argc db "argc : %ld", 10, 0
|
||||||
|
fmt_argv db "argv[%d]: %s", 10, 0
|
||||||
|
|
||||||
|
global main
|
||||||
|
extern printf
|
||||||
|
|
||||||
|
section .text
|
||||||
|
main:
|
||||||
|
; rdi = argc
|
||||||
|
; rsi = argv
|
||||||
|
mov [argc], rdi ; salvar argc
|
||||||
|
mov [argv], rsi ; salvar argv[0]
|
||||||
|
|
||||||
|
; Imprimir com: printf("argc : %ld", argc);
|
||||||
|
mov rdi, fmt_argc ; primeiro argumento: formato
|
||||||
|
mov rsi, [argc] ; segundo argumento: argc (qword = long)
|
||||||
|
xor rax, rax ; terminação de argumentos
|
||||||
|
call printf
|
||||||
|
|
||||||
|
; preparar o laço: i = 0
|
||||||
|
xor rcx, rcx ; i = 0
|
||||||
|
mov rbx, [argv] ; rbx = argv base
|
||||||
|
mov r8, [argc] ; r8 = argc
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
cmp rcx, r8 ; compara i com argc
|
||||||
|
jge .done ; se i >= argc, fim
|
||||||
|
|
||||||
|
; Imprimir com: printf("argv[%d]: %s\n", i, argv[i]);
|
||||||
|
mov rdi, fmt_argv ; primeiro argumento: formato
|
||||||
|
mov rsi, rcx ; segundo argumento: i
|
||||||
|
mov rdx, [rbx + rcx*8] ; terceiro argumento: argv[i]
|
||||||
|
xor rax, rax ; terminação de argumentos
|
||||||
|
push rcx ; salvar rcx (caller saved) na pilha
|
||||||
|
push r8 ; salvar r8 (caller saved) na pilha
|
||||||
|
call printf
|
||||||
|
pop r8 ; restaurar rcx
|
||||||
|
pop rcx ; restaurar rcx
|
||||||
|
|
||||||
|
inc rcx
|
||||||
|
jmp .loop
|
||||||
|
|
||||||
|
.done:
|
||||||
|
xor eax, eax ; retorno de main: (int)0
|
||||||
|
ret
|
9
curso/exemplos/06/exit42.asm
Normal file
9
curso/exemplos/06/exit42.asm
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
; Retorna 42 como estado de término
|
||||||
|
|
||||||
|
section .text
|
||||||
|
global _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
mov rax, 60 ; syscall: exit
|
||||||
|
mov rdi, 42 ; código de saída
|
||||||
|
syscall
|
159
curso/exemplos/06/print_utils.asm
Normal file
159
curso/exemplos/06/print_utils.asm
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; print_utils.asm
|
||||||
|
; Sub-rotinas:
|
||||||
|
; - print_char(rdi = caractere)
|
||||||
|
; - print_str(rdi = ptr string \0-terminated)
|
||||||
|
; - print_int(rax = inteiro, sem newline)
|
||||||
|
; Macros:
|
||||||
|
; - SAVE_REGS: salva registradores voláteis
|
||||||
|
; - RESTORE_REGS: restaura registradores salvos
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
|
||||||
|
%macro SAVE_REGS 0
|
||||||
|
push rax
|
||||||
|
push rbx
|
||||||
|
push rcx
|
||||||
|
push rdx
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
push r8
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
|
push r11
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro RESTORE_REGS 0
|
||||||
|
pop r11
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
|
pop r8
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rdx
|
||||||
|
pop rcx
|
||||||
|
pop rbx
|
||||||
|
pop rax
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
int_buf resb 22 ; buffer para int e char
|
||||||
|
|
||||||
|
section .text
|
||||||
|
global print_char
|
||||||
|
global print_str
|
||||||
|
global print_int
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; void print_char(rdi = caractere)
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
print_char:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
|
SAVE_REGS
|
||||||
|
|
||||||
|
mov al, dil ; coloca o caractere em al (parte baixa de rax)
|
||||||
|
mov byte [int_buf], al ; usa o mesmo buffer global
|
||||||
|
|
||||||
|
mov rax, 1 ; syscall write
|
||||||
|
mov rdi, 1 ; stdout
|
||||||
|
lea rsi, [int_buf]
|
||||||
|
mov rdx, 1
|
||||||
|
syscall
|
||||||
|
|
||||||
|
RESTORE_REGS
|
||||||
|
|
||||||
|
mov rsp, rbp
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; void print_str(rdi = ptr string \0-terminated)
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
print_str:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
|
SAVE_REGS
|
||||||
|
|
||||||
|
mov rsi, rdi ; ponteiro string
|
||||||
|
xor rcx, rcx
|
||||||
|
|
||||||
|
.count_loop:
|
||||||
|
cmp byte [rsi + rcx], 0
|
||||||
|
je .write
|
||||||
|
inc rcx
|
||||||
|
jmp .count_loop
|
||||||
|
|
||||||
|
.write:
|
||||||
|
mov rax, 1 ; syscall write
|
||||||
|
mov rdi, 1 ; stdout
|
||||||
|
mov rdx, rcx ; tamanho string
|
||||||
|
syscall
|
||||||
|
|
||||||
|
RESTORE_REGS
|
||||||
|
|
||||||
|
mov rsp, rbp
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
; void print_int(rax = inteiro, sem newline)
|
||||||
|
; ------------------------------------------------------------
|
||||||
|
print_int:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
|
SAVE_REGS
|
||||||
|
|
||||||
|
mov rdi, rax
|
||||||
|
lea rsi, [int_buf + 21] ; aponta para o fim do buffer
|
||||||
|
mov byte [rsi], 0 ; opcional: zero-termina
|
||||||
|
|
||||||
|
cmp rdi, 0
|
||||||
|
jne .convert
|
||||||
|
|
||||||
|
; zero
|
||||||
|
dec rsi
|
||||||
|
mov byte [rsi], '0'
|
||||||
|
jmp .write
|
||||||
|
|
||||||
|
.convert:
|
||||||
|
mov rax, rdi
|
||||||
|
mov rbx, 10
|
||||||
|
xor rcx, rcx
|
||||||
|
|
||||||
|
cmp rdi, 0
|
||||||
|
jge .conv_loop
|
||||||
|
|
||||||
|
neg rax
|
||||||
|
mov rcx, 1 ; sinal negativo
|
||||||
|
|
||||||
|
.conv_loop:
|
||||||
|
xor rdx, rdx
|
||||||
|
div rbx
|
||||||
|
add dl, '0'
|
||||||
|
dec rsi
|
||||||
|
mov [rsi], dl
|
||||||
|
test rax, rax
|
||||||
|
jnz .conv_loop
|
||||||
|
|
||||||
|
test rcx, rcx
|
||||||
|
jz .write
|
||||||
|
|
||||||
|
dec rsi
|
||||||
|
mov byte [rsi], '-'
|
||||||
|
|
||||||
|
.write:
|
||||||
|
mov rax, 1 ; syscall write
|
||||||
|
mov rdi, 1 ; stdout
|
||||||
|
mov rdx, int_buf + 21
|
||||||
|
sub rdx, rsi
|
||||||
|
syscall
|
||||||
|
|
||||||
|
RESTORE_REGS
|
||||||
|
|
||||||
|
mov rsp, rbp
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
20
curso/exemplos/06/prog.asm
Normal file
20
curso/exemplos/06/prog.asm
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
section .data
|
||||||
|
fmt db "Programa: %s", 10, 0
|
||||||
|
|
||||||
|
global main ; símbolo chamado por _start de crt0.o
|
||||||
|
extern printf ; (opcional) usar funções da libc
|
||||||
|
|
||||||
|
section .text
|
||||||
|
main:
|
||||||
|
; argc → rdi
|
||||||
|
; argv → rsi
|
||||||
|
; envp → rdx (não obrigatório)
|
||||||
|
|
||||||
|
; Exemplo: imprimir argv[0]
|
||||||
|
mov rdi, fmt
|
||||||
|
mov rsi, [rsi] ; argv[0]
|
||||||
|
xor rax, rax ; terminação de argumentos (printf é variádica)
|
||||||
|
call printf
|
||||||
|
|
||||||
|
mov eax, 0 ; retorno de 'main' = (int)0
|
||||||
|
ret
|
Loading…
Add table
Reference in a new issue