pbn/curso/exemplos/06/print_utils.asm
2025-05-25 12:27:43 -03:00

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