159 lines
2.6 KiB
NASM
159 lines
2.6 KiB
NASM
; ------------------------------------------------------------
|
|
; 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
|
|
|