hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/aoc-2025/utils/io.asm
blob: 2081671451181c10dbf113ce36e2fd89a63b1c55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
; 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