From a52678034edaf8f2a27e3341845e2f8ec2fd9013 Mon Sep 17 00:00:00 2001 From: hachem Date: Sat, 6 Dec 2025 09:14:34 +0100 Subject: [setup]: x86 -> x64 --- src/Day1.asm | 418 ++++++++++++++++++++++++++--------------------------------- src/Day2.asm | 23 ++-- 2 files changed, 200 insertions(+), 241 deletions(-) (limited to 'src') diff --git a/src/Day1.asm b/src/Day1.asm index 34b0361..8ba8f0e 100644 --- a/src/Day1.asm +++ b/src/Day1.asm @@ -1,57 +1,15 @@ ; Advent of Code 2025 - Day 1 -; -; #include -; #include -; #include -; #include -; -; int main(void) -; { -; FILE* input = fopen("input/day1.txt", "r"); -; -; int32_t angle1 = 50; -; int32_t angle2 = 50; -; -; int32_t password1 = 0; -; int32_t password2 = 0; -; -; char line[256]; -; while (fgets(line, sizeof(line), input)) -; { -; int32_t direction = (line[0] == 'L') ? -1 : 1; -; int32_t steps = atoi(line + 1); -; -; // part 1 -; angle1 += direction * steps; -; angle1 %= 100; -; if (angle1 < 0) -; angle1 += 100; -; if (angle1 == 0) -; password1++; -; -; // part 2 -; for (int i = 0; i < steps; i++) -; { -; angle2 = ((angle2 + direction) % 100 + 100) % 100; -; if (angle2 == 0) -; password2++; -; } -; } -; -; fclose(input); -; -; printf("Password 1: %d\n", password1); -; printf("Password 2: %d\n", password2); -; } +bits 64 +default rel global _start -%define SYS_EXIT 1 -%define SYS_READ 3 -%define SYS_WRITE 4 -%define SYS_OPEN 5 -%define SYS_CLOSE 6 +%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 @@ -79,280 +37,278 @@ section .text _start: ; open file - mov eax, SYS_OPEN - mov ebx, inputPath - mov ecx, O_RDONLY - int 0x80 + mov rax, SYS_OPEN + mov rdi, inputPath + mov rsi, O_RDONLY + xor rdx, rdx + syscall - mov esi, eax ; fd in ESI - mov dword [lineLen], 0 ; no chars in current line yet + mov r12, rax ; fd in R12 + mov dword [lineLen], 0 ; no chars in current line yet ReadLoop: ; read up to 4096 bytes - mov eax, SYS_READ - mov ebx, esi - mov ecx, buffer - mov edx, 4096 - int 0x80 + mov rax, SYS_READ + mov rdi, r12 + mov rsi, buffer + mov rdx, 4096 + syscall - cmp eax, 0 - jle EOF ; <=0 -> EOF or error + cmp rax, 0 + jle EOF ; <=0 -> EOF or error - mov edi, buffer ; scan pointer - mov ebp, eax ; bytes remaining in this chunk + mov rdi, buffer ; scan pointer + mov rbp, rax ; bytes remaining in this chunk ScanChunk: - cmp ebp, 0 - je ReadLoop ; chunk done, read next + cmp rbp, 0 + je ReadLoop ; chunk done, read next - mov al, [edi] + mov al, [rdi] ; windows can be a fucking bitch ; handle (CR) -> just skip - cmp al, 13 - je SkipCR + cmp al, 13 + je SkipCR ; handle LF (10) -> end of line - cmp al, 10 - je EndOfLine + cmp al, 10 + je EndOfLine ; normal character -> append to lineBuffer if space left - mov edx, [lineLen] - cmp edx, 255 ; leave 1 byte for NULL - jae SkipStore ; ignore extra characters if too long - mov [lineBuffer+edx], al - inc edx - mov [lineLen], edx + mov edx, [lineLen] + cmp edx, 255 ; leave 1 byte for NULL + jae SkipStore ; ignore extra characters if too long + mov [lineBuffer+rdx], al + inc edx + mov [lineLen], edx SkipStore: - inc edi - dec ebp - jmp ScanChunk + inc rdi + dec rbp + jmp ScanChunk SkipCR: - inc edi - dec ebp - jmp ScanChunk + inc rdi + dec rbp + jmp ScanChunk EndOfLine: ; terminate current line - mov edx, [lineLen] - mov byte [lineBuffer+edx], 0 + mov edx, [lineLen] + mov byte [lineBuffer+rdx], 0 ; if line isn't empty, process it - cmp edx, 0 - je LineDone + cmp edx, 0 + je LineDone - push esi - push edi - mov esi, lineBuffer - call HandleLine - pop edi - pop esi + push rdi + mov rsi, lineBuffer + call HandleLine + pop rdi LineDone: - mov dword [lineLen], 0 ; reset line length - inc edi - dec ebp - jmp ScanChunk + mov dword [lineLen], 0 ; reset line length + inc rdi + dec rbp + jmp ScanChunk ; process last line if not newline-terminated, then print result EOF: ; if there is a partial line at EOF, process it - mov edx, [lineLen] - cmp edx, 0 - jle PrintResults - mov byte [lineBuffer+edx], 0 + mov edx, [lineLen] + cmp edx, 0 + jle PrintResults + mov byte [lineBuffer+rdx], 0 - push esi - mov esi, lineBuffer - call HandleLine - pop esi + mov rsi, lineBuffer + call HandleLine PrintResults: - mov ecx, label1 - call PrintString - mov eax, [password1] - call PrintInt + mov rcx, label1 + call PrintString + mov eax, [password1] + call PrintInt ; newline - mov eax, SYS_WRITE - mov ebx, STDOUT - mov ecx, newline - mov edx, 1 - int 0x80 + mov rax, SYS_WRITE + mov rdi, STDOUT + mov rsi, newline + mov rdx, 1 + syscall - mov ecx, label2 - call PrintString - mov eax, [password2] - call PrintInt + mov rcx, label2 + call PrintString + mov eax, [password2] + call PrintInt ; new linhe - mov eax, SYS_WRITE - mov ebx, STDOUT - mov ecx, newline - mov edx, 1 - int 0x80 - - mov eax, SYS_CLOSE - mov ebx, esi - int 0x80 - mov eax, SYS_EXIT - xor ebx, ebx - int 0x80 - -; Handle one line: ESI -> "L123" or "R45" + mov rax, SYS_WRITE + mov rdi, STDOUT + mov rsi, newline + mov rdx, 1 + syscall + + mov rax, SYS_CLOSE + mov rdi, r12 + syscall + mov rax, SYS_EXIT + xor rdi, rdi + syscall + +; Handle one line: RSI -> "L123" or "R45" HandleLine: - mov al, [esi] - cmp al, 'L' - je .left - mov ebx, 1 ; direction = +1 for 'R' or anything else - jmp .after + mov al, [rsi] + cmp al, 'L' + je .left + mov ebx, 1 ; direction = +1 for 'R' or anything else + jmp .after .left: - mov ebx, -1 ; direction = -1 for 'L' + mov ebx, -1 ; direction = -1 for 'L' .after: - inc esi ; skip 'L' or 'R' - call ParseInt ; EAX = steps - mov ecx, eax + inc rsi ; skip 'L' or 'R' + call ParseInt ; EAX = steps + mov ecx, eax ; Part 1 P1_Start: - mov eax, ecx - imul eax, ebx - add eax, [angle1] - call NormalizeAngle - mov [angle1], eax - cmp eax, 0 - jne P2_Start - mov edi, password1 - mov edx, [edi] - inc edx - mov [edi], edx + mov eax, ecx + imul eax, ebx + add eax, [angle1] + call NormalizeAngle + mov [angle1], eax + cmp eax, 0 + jne P2_Start + mov rdi, password1 + mov edx, [rdi] + inc edx + mov [rdi], edx ; Part 2 P2_Start: - mov edi, password2 + mov rdi, password2 .loop: - test ecx, ecx - jle P2_Exit - dec ecx + test ecx, ecx + jle P2_Exit + dec ecx - mov eax, [angle2] - call UpdateAngleCount - mov [angle2], eax + mov eax, [angle2] + call UpdateAngleCount + mov [angle2], eax - jmp .loop + jmp .loop P2_Exit: ret ; normalize eax to 0..99 NormalizeAngle: - cmp eax, 0 - jl .add - cmp eax, 100 - jl .done - sub eax, 100 - jmp NormalizeAngle + cmp eax, 0 + jl .add + cmp eax, 100 + jl .done + sub eax, 100 + jmp NormalizeAngle .add: - add eax, 100 - jmp NormalizeAngle + add eax, 100 + jmp NormalizeAngle .done: ret -; eax = angle, ebx = direction, edi = password counter addr +; eax = angle, ebx = direction, rdi = password counter addr UpdateAngleCount: - add eax, ebx - call NormalizeAngle - - cmp eax, 0 - jne .done - mov edx, [edi] - inc edx - mov [edi], edx + add eax, ebx + call NormalizeAngle + + cmp eax, 0 + jne .done + mov edx, [rdi] + inc edx + mov [rdi], edx .done: ret ; parse ASCII integer into EAX ParseInt: - xor eax, eax ; result = 0 + xor eax, eax ; result = 0 .parseLoop: - mov dl, [esi] - cmp dl, '0' - jl .done - cmp dl, '9' - jg .done + mov dl, [rsi] + cmp dl, '0' + jl .done + cmp dl, '9' + jg .done - sub dl, '0' ; digit value 0..9 - movzx edx, dl + sub dl, '0' ; digit value 0..9 + movzx edx, dl - imul eax, eax, 10 ; result *= 10 - add eax, edx ; result += digit + imul eax, eax, 10 ; result *= 10 + add eax, edx ; result += digit - inc esi - jmp .parseLoop + inc rsi + jmp .parseLoop .done: ret PrintInt: - mov edi, numberBuffer+15 ; write digits from the end - mov byte [edi], 0 ; terminator - dec edi - - cmp eax, 0 - jne .convert - mov byte [edi], '0' - jmp .finish + mov edi, numberBuffer+15 ; write digits from the end + mov byte [rdi], 0 ; terminator + dec rdi + + cmp eax, 0 + jne .convert + mov byte [rdi], '0' + jmp .finish .convert: ; we will repeatedly compute: ; q = eax / 10 ; r = eax % 10 ; using only subtraction .nextDigit: - mov edx, eax ; tmp = current value - mov ecx, 0 ; q = 0 + mov edx, eax ; tmp = current value + mov ecx, 0 ; q = 0 - cmp edx, 10 ; if < 0, q=0, r=edx - jb .lastDigit + cmp edx, 10 ; if < 0, q=0, r=edx + jb .lastDigit .subLoop: - sub edx, 10 - inc ecx ; q++ - cmp edx, 10 - jae .subLoop ; while tmp >= 10 + sub edx, 10 + inc ecx ; q++ + cmp edx, 10 + jae .subLoop ; while tmp >= 10 .lastDigit: ; now: ; ecx = quotient ; edx = remainder (0..9) - add dl, '0' - mov [edi], dl ; store digit - dec edi - mov eax, ecx ; eax = quotient - test eax, eax - jnz .nextDigit ; more digits to extract? - - inc edi ; move to first digit + add dl, '0' + mov [rdi], dl ; store digit + dec rdi + mov eax, ecx ; eax = quotient + test eax, eax + jnz .nextDigit ; more digits to extract? + + inc rdi ; move to first digit .finish: - mov eax, SYS_WRITE - mov ebx, STDOUT - mov ecx, edi - mov edx, numberBuffer+15 - sub edx, edi ; length - int 0x80 + mov rax, SYS_WRITE + mov rsi, rdi ; buffer pointer + mov rdi, STDOUT + mov rdx, numberBuffer+15 + sub rdx, rsi ; length + syscall ret PrintString: - push ecx - push edx - mov edx, 0 + push rcx + push rdx + mov rdx, 0 .count: - cmp byte [ecx+edx], 0 - je .doneCount - inc edx - jmp .count + cmp byte [rcx+rdx], 0 + je .doneCount + inc rdx + jmp .count .doneCount: - mov eax, SYS_WRITE - mov ebx, STDOUT - int 0x80 + mov rax, SYS_WRITE + mov rdi, STDOUT + mov rsi, rcx + syscall - pop edx - pop ecx + pop rdx + pop rcx ret diff --git a/src/Day2.asm b/src/Day2.asm index d524d7c..7e154da 100644 --- a/src/Day2.asm +++ b/src/Day2.asm @@ -1,9 +1,12 @@ ; Advent of Code 2025 - Day 2 +bits 64 +default rel + global _start -%define SYS_EXIT 1 -%define SYS_WRITE 4 +%define SYS_EXIT 60 +%define SYS_WRITE 1 %define STDOUT 1 @@ -13,12 +16,12 @@ section .data section .text _start: - mov eax, SYS_WRITE - mov ebx, STDOUT - mov ecx, message - mov edx, length - int 0x80 + mov rax, SYS_WRITE + mov rdi, STDOUT + mov rsi, message + mov rdx, length + syscall - mov eax, SYS_EXIT - xor ebx, ebx - int 0x80 + mov rax, SYS_EXIT + xor rdi, rdi + syscall -- cgit v1.3