; utils/io.asm - shared syscall constants, file reading, and output helpers. ; This file is %included (not linked) by each day's solution. %define SYS_EXIT 60 %define SYS_READ 0 %define SYS_WRITE 1 %define SYS_OPEN 2 %define SYS_CLOSE 3 %define O_RDONLY 0 %define STDOUT 1 section .data newline db 10 section .bss number_buffer resb 32 section .text ; read_file: open the path in RDI read-only, read up to RDX bytes into the ; buffer in RSI, close, and return the number of bytes read in RAX. read_file: mov r8, rsi ; buffer base mov r9, rdx ; capacity mov rax, SYS_OPEN mov rsi, O_RDONLY xor rdx, rdx syscall mov r10, rax ; fd xor r11, r11 ; bytes read so far .loop: mov rax, SYS_READ mov rdi, r10 lea rsi, [r8 + r11] mov rdx, r9 sub rdx, r11 syscall cmp rax, 0 jle .done add r11, rax jmp .loop .done: mov rax, SYS_CLOSE mov rdi, r10 syscall mov rax, r11 ret print_newline: mov rax, SYS_WRITE mov rdi, STDOUT mov rsi, newline mov rdx, 1 syscall ret ; print_int64: print the unsigned integer in RAX in decimal. print_int64: mov rdi, number_buffer+31 mov byte [rdi], 0 dec rdi cmp rax, 0 jne .conv mov byte [rdi], '0' jmp .done .conv: mov rbx, 10 .next: xor rdx, rdx div rbx add dl, '0' mov [rdi], dl dec rdi test rax, rax jnz .next inc rdi .done: mov rax, SYS_WRITE mov rsi, rdi mov rdi, STDOUT mov rdx, number_buffer+31 sub rdx, rsi syscall ret ; print_string: print the NUL-terminated string pointed to by RCX. print_string: push rcx push rdx mov rdx, 0 .length: cmp byte [rcx+rdx], 0 je .submit inc rdx jmp .length .submit: mov rax, SYS_WRITE mov rdi, STDOUT mov rsi, rcx syscall pop rdx pop rcx ret