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
|