print_args.asm #16
```asm
; 1. obter o endereço armazenado em rsp (endereço de ARGC)
; - obviamente o endereço já está em rsp
; - o que nós queremos é o dado neste endereço: como obter este dado?
; - armazenar o valor no endereço em um registrador
; 2. converter o valor de ARGC (uint64) em string (cadeia de caracteres terminado por '\0')
; - (ex. 123) :
; - 123 / 10 = 12 resto 3 -> + 48 ou 0x30 -> 0x33
; - 12 / 10 = 1 resto 2 -> + 48 ou 0x30 -> 0x32
; - 1 / 10 = 0 resto 1 -> +48 ou 0x30 -> 0x31
; 3. imprimir ARGC
; - imprimir os bytes encontrados na ordem inversa
; 4. zerar um registrador para servir de índice
; 5. obter o endereço do elemento de ARGV
; - somar rsp + (8 bytes * índice) + 8
; - armazenar o endereço em um registrador
; 6. obter o valor do elemento de ARGV (este é o endereço do argumento em si)
; - armazenar a indireção do endereço em outro registrador
; - comparar o valor de ARGV com 0 (NULL)
; - se for NULL: encerra/termina
; 7. imprimir string do argumento
; - imprimir cada byte da string até encontrar o caractere '\0'
; 8. avançar para o próximo endereço da pilha (pode ser NULL ou próximo elemento de ARGV)
; - incrementar o índice
; - voltar ao passo 5
;
; 1010 = 10
; 1010 = 10
;----------- XOR
; 0000 = 00
;
section .text
global _start
_start:
mov rax, [rsp]
call print_int
; Quebra de linha
mov rdi, 10
call print_char
xor rcx, rcx
.args_loop:
lea rdx, [rsp + 8 * rcx + 8]
mov rsi, [rdx]
test rsi, rsi
jz _exit
call print_str
; Quebra de linha
mov rdi, 10
call print_char
inc rcx
jmp .args_loop
_exit:
mov rax, 60
xor rdi, rdi
syscall
print_str:
push rcx ; salva rcx na pilha
push rdx ; salva rdx na pilha
mov rax, 1 ; syscall write
mov rdi, 1 ; stdout
mov rdx, 1 ; imprimir 1 byte
.char_loop:
cmp byte [rsi], 0 ; trata-se do byte 0?
je .done ; se sim, termina
syscall
inc rsi ; próximo byte
jmp .char_loop
.done:
pop rdx
pop rcx
ret
print_char:
push rcx
push rdx
push rdi ; Caractere a imprimir
mov rax, 1 ; syscall write
mov rdi, 1 ; stdout
mov rsi, rsp ; onde está o que vamos imprimir?
mov rdx, 1 ; imprimir 1 byte
syscall
pop rdi
pop rdx
pop rcx
ret
print_int:
xor rdx, rdx ; zera rdx
mov rcx, 10 ; rcx = 10
div rcx ; rax = rdx:rax / rcx, rdx = resto
push rdx ; rdx (primeiro algarismo) vai para a pilha
cmp rax, 0 ; rax = 0?
je print_alg ; se sim, hora de imprimir cada algarismo
call print_int ; se não, separar o próximo algarismo
print_alg:
add qword [rsp], 0x30 ; converte o algarismo para código ascii
mov rsi, rsp ; onde está o que vamos imprimir
pop rcx ; retira o item da pilha
mov rax, 1 ; syscall write
mov rdi, 1 ; stdout
mov rdx, 1 ; imprimir um byte
syscall
ret
```
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?