advent_of_code_2024_asm/part2/main.asm

316 lines
5.1 KiB
NASM

default rel
extern printf
global exitcode
section .data
buf: dq 0
dbuf: dw 0
path: db "./input.txt", 0
nb_lines: dw 1000
fmt: db "Value %s: %d", 10, 0
fd_str: db "file descriptor", 0
close_str: db "close", 0
content_str: db "Content: '%s'", 10, 0
nbr_str: db "number", 0
exitcode: dw 0
section .text
global _start
printvalue:
push rbp
mov rbp, rsp
sub rsp, 8H
;; args
mov dword [rbp-8H], edi
mov dword [rbp-4H], esi
;; printf
xor rax, rax
lea rdi, [fmt] ; format
mov esi, dword [rbp-8H] ; arg1
mov edx, dword [rbp-4H] ; arg2
call printf
;; leave
mov rsp, rbp
pop rbp
ret
;; End of printvalue
readval:
;; rdi: FILE DESCRIPTOR
;; rsi: offset
push rbp
mov rbp, rsp
sub rsp, 16H
mov qword [rbp-8H], rsi
mov qword [rbp-16H], rdi
;; sys_read
mov rax, 0 ; sys_read
;; rdi has already file descriptor
mov rdi, qword [rbp-16H]
mov rsi, buf
mov rdx, 5H
syscall
;; Go to the next number
mov rax, 8 ; sys_lseek
mov rdi, qword [rbp-16H] ; fd
mov rsi, qword [rbp-8H] ; advance by n chars
mov rdx, 1 ; origin
syscall
;; convert buf to an int
xor ebx, ebx
mov esi, buf
mov ecx, 5
.next_digit:
movzx eax, byte [esi]
inc rsi
sub al, '0' ; convert ascii to number (remove offset of the 0 digit)
imul ebx, 10
add ebx, eax ; rbx = rbx*10 + rax
loop .next_digit ; loop until ecx = 0
xor rax, rax
mov eax, ebx
mov rsp, rbp
pop rbp
ret
;; end of readval1
popmin:
push rbp
mov rbp, rsp
sub rsp, 22H
;; 8H, 0 -> min value address
;; 12H, 8H -> min value
;; 14H, 12H -> loop counter
;; 22H, 14H : current address
;; rdi: list effective address
mov qword [rbp-8H], rdi
mov qword [rbp-22H], rdi ; current address
mov esi, [rdi]
mov dword [rbp-12H], esi
mov ecx, 1000
minloop:
mov word [rbp-14H], cx
mov r9, qword [rbp-22H]
mov edi, [r9] ; current value
mov esi, dword [rbp-12H] ; min value
cmp esi, 0
je updatemin
cmp edi, 0
je next ; skip zeroes
cmp edi, esi
jle updatemin
jmp next
updatemin:
mov r9, qword [rbp-22H]
mov dword [rbp-12H], edi
mov qword [rbp-8H], r9
next:
mov r9, qword [rbp-22H]
add r9, 4H
mov qword [rbp-22H], r9
dec cx
jnz minloop
mov rax, qword [rbp-8H]
mov dword [rax], 0H
mov eax, dword [rbp-12H]
mov rsp, rbp
pop rbp
ret
_start:
push rbp
mov rbp, rsp
sub rsp, 2000H
;; 8H -> 0 : file_descriptor
;; 12H -> 8H : buffer for readvalue
;; 14H -> 12H : current line
;; 19H -> 17H: read loop counter
;; 2000H -> 1060H : list 1 (1000 digits of 4 bytes)
;; 1000H -> 60H : list 2
mov rax, 2 ; sys_open
lea rdi, [path]
xor rsi, rsi
xor rdx, rdx
syscall
;; store file descriptor
mov qword [rbp-8H], rax
;; print file descriptor
lea rdi, [fd_str]
mov rsi, rax
call printvalue
;; exit if open failed
cmp dword [rbp-8H], 0
jl exit
mov word [rbp-14H], 0H ; line number
mov cx, [nb_lines] ; number of lines
loop0:
mov [rbp-19H], cx ; store loop counter
;; read the 1st value
mov rdi, qword [rbp-8H]
mov rsi, 3H ; mov to the second number
call readval
; store the read value
mov [dbuf], eax
;; calculate list position
xor rax, rax
mov ax, word [rbp-14H]
mov bx, 4H
mul bx
;; 14H -> 12H : line counter
mov rbx, 2000H
sub rbx, rax
mov r9, rbp
sub r9, rbx
; move the value to its position
mov eax, [dbuf]
mov dword [r9], eax
;; read the 2nd value
mov rdi, qword [rbp-8H]
mov rsi, 1H ; mov to the next line
call readval
; store the read value
mov [dbuf], eax
;; calculate list position
xor rax, rax
mov ax, word [rbp-14H]
mov bx, 4H
mul bx
mov rbx, 1000H
sub rbx, rax
mov r9, rbp
sub r9, rbx
; move the value to its position
mov eax, [dbuf]
mov dword [r9], eax
xor rax, rax
mov ax, word [rbp-14H]
inc ax
mov word [rbp-14H], ax
mov cx, [rbp-19H] ; restore loop counter
dec cx
jnz loop0
mov qword [rbp-42H], 0 ; sum = 0
mov ecx, 1000
sumloop:
mov word [rbp-19H], cx
;; 50H - 46H : min1
;; 46H - 42H : min2
;; 42H - 34H : sum
lea rdi, [rbp-2000H]
call popmin
mov dword [rbp-50H], eax
lea rdi, [rbp-1000H]
call popmin
mov dword [rbp-46H], eax
xor rax, rax
mov eax, dword [rbp-50H]
mov ebx, dword [rbp-46H]
cmp eax, ebx
jge a
jmp b
a:
sub eax, ebx
jmp sum
b:
sub ebx, eax
mov eax, ebx
jmp sum
sum:
mov rbx, qword [rbp-42H]
add rbx, rax
mov qword [rbp-42H], rbx
mov cx, word [rbp-19H]
dec cx
cmp cx, 0
jnz sumloop
;; print sys_close result
lea rdi, [nbr_str]
mov rsi, qword [rbp-42H]
call printvalue
close_file:
;; sys_close
mov rax, 3 ; sys_close
mov edi, dword [rbp-8H]
syscall
;; print sys_close result
lea rdi, [close_str]
mov rsi, rax
call printvalue
exit:
;; EXIT
mov rax, 60 ; sys_exit
mov rdi, [exitcode]
syscall