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