1
0
Fork 0

Compare commits

...

2 Commits

Author SHA1 Message Date
chylex 9ba92014ab
Rewrite 2015 - Day 1 in x64 assembly 2022-02-11 21:03:51 +01:00
chylex c7433b0a82
Add 2015 - Day 2 - Part 1 2022-02-11 20:46:23 +01:00
10 changed files with 1170 additions and 47 deletions

View File

@ -2,10 +2,8 @@
<project version="4">
<component name="CMakeSharedSettings">
<configurations>
<configuration PROFILE_NAME="Debug x86" ENABLED="true" CONFIG_NAME="Debug" TOOLCHAIN_NAME="Visual Studio x86" />
<configuration PROFILE_NAME="Release x86" ENABLED="true" CONFIG_NAME="Release" TOOLCHAIN_NAME="Visual Studio x86" />
<configuration PROFILE_NAME="Debug x64" ENABLED="true" CONFIG_NAME="Debug" TOOLCHAIN_NAME="Visual Studio x64" />
<configuration PROFILE_NAME="Release x64" ENABLED="true" CONFIG_NAME="Release" TOOLCHAIN_NAME="Visual Studio x64" />
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" TOOLCHAIN_NAME="Visual Studio x64" />
<configuration PROFILE_NAME="Release" ENABLED="true" CONFIG_NAME="Release" TOOLCHAIN_NAME="Visual Studio x64" />
</configurations>
</component>
</project>

View File

@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="2015 - Day 01" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" WORKING_DIR="file://$PROJECT_DIR$/2015/01" PASS_PARENT_ENVS_2="true" PROJECT_NAME="AOC" TARGET_NAME="AOC_2015_01" CONFIG_NAME="Debug x86" RUN_TARGET_PROJECT_NAME="AOC" RUN_TARGET_NAME="AOC_2015_01">
<configuration default="false" name="2015 - Day 01" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" WORKING_DIR="file://$PROJECT_DIR$/2015/01" PASS_PARENT_ENVS_2="true" PROJECT_NAME="AOC" TARGET_NAME="AOC_2015_01" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="AOC" RUN_TARGET_NAME="AOC_2015_01">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>

View File

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="2015 - Day 02" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" WORKING_DIR="file://$PROJECT_DIR$/2015/02" PASS_PARENT_ENVS_2="true" PROJECT_NAME="AOC" TARGET_NAME="AOC_2015_02" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="AOC" RUN_TARGET_NAME="AOC_2015_02">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
</component>

6
2015/.gitignore vendored
View File

@ -1,4 +1,2 @@
/cmake-build-debug-x86/
/cmake-build-debug-x64/
/cmake-build-release-x86/
/cmake-build-release-x64/
/cmake-build-debug/
/cmake-build-release/

View File

@ -1,25 +1,29 @@
bits 32
bits 64
default rel
section .text
extern _print
global _entryPoint
extern print
global entryPoint
_entryPoint:
enter 0,0
push ebx
push edi
entryPoint:
push rbp
mov rbp, rsp
xor eax, eax ; current floor
xor ebx, ebx ; current instruction
xor ecx, ecx ; instruction counter
mov edx, [ ebp + 8 ] ; instruction pointer
mov edi, -1 ; first entered basement (-1 = unset)
push rbx
push rdi
sub rsp, 32
mov rdx, rcx ; instruction pointer
xor rax, rax ; current floor
xor rbx, rbx ; current instruction
xor rcx, rcx ; instruction counter
mov rdi, -1 ; first entered basement (-1 = unset)
.instructionLoop:
inc ecx ; increment instruction counter
mov bl, [ edx ] ; bl = instructions[edx]
inc edx ; increment instruction pointer
inc rcx ; increment instruction counter
movzx rbx, byte [ rdx ] ; bl = instructions[rdx]
inc rdx ; increment instruction pointer
cmp bl, '(' ; left parenthesis...
je .moveUpFloor ; moves up a floor
@ -28,36 +32,34 @@ _entryPoint:
jmp .end ; unknown character skips to the end
.moveUpFloor:
inc eax
inc rax
jmp .instructionLoop
.moveDownFloor:
dec eax
cmp eax, -1 ; check if we entered the basement
dec rax
cmp rax, -1 ; check if we entered the basement
je .onEnteredBasement
jmp .instructionLoop
.onEnteredBasement:
cmp edi, -1 ; check if firstEnteredBasement has not been set yet
cmp rdi, -1 ; check if firstEnteredBasement has not been set yet
jne .instructionLoop ; if it was already set, go to next instruction
mov edi, ecx ; set first entered basement to instruction counter
mov rdi, rcx ; set first entered basement to instruction counter
jmp .instructionLoop
.end:
push eax
push dword print_final_floor
call _print
pop eax
pop eax
lea rcx, [ print_final_floor ]
mov rdx, rax
call print
push edi
push dword print_first_entered_basement
call _print
pop edi
pop edi
lea rcx, [ print_first_entered_basement ]
mov rdx, rdi
call print
add rsp, 32
pop rdi
pop rbx
pop edi
pop ebx
leave
ret

5
2015/02/CMakeLists.txt Normal file
View File

@ -0,0 +1,5 @@
set(PROJECT_NAME AOC_2015_02)
project(${PROJECT_NAME} C ASM_NASM)
add_executable(${PROJECT_NAME} main.asm ../utils/main.c ../utils/file.h ../utils/benchmark.h)

1000
2015/02/input/1.txt Normal file

File diff suppressed because it is too large Load Diff

113
2015/02/main.asm Normal file
View File

@ -0,0 +1,113 @@
bits 64
default rel
section .text
extern print
global entryPoint
entryPoint:
push rbp
mov rbp, rsp
push rbx
push r12
sub rsp, 32
; rax = reserved for math
; rdx = reserved for math
; rbx = value of current character of input string
; rcx = pointer to current character of input string
; r8 = return value for nextNumber
; r9 = first dimension
; r10 = second dimension
; r11 = third dimension
; r12 = total wrapping paper required
xor rdx, rdx
xor r12, r12
.nextLine:
call .nextNumber
mov r9, r8 ; save first dimension to r9
call .nextNumber
mov r10, r8 ; save second dimension to r10
call .nextNumber
mov r11, r8 ; save third dimension to r11
.sort1: ; initiate bubble sort of the three dimensions (possible configurations 123; 132; 213; 231; 312; 321)
cmp r9, r10 ; compare first pair of dimensions
jb .sort2 ; if they are already sorted, skip ahead (123; 132; 231)
xchg r9, r10 ; otherwise, swap the first pair (213->123; 312->132; 321->231)
.sort2:
cmp r10, r11 ; compare last pair of dimensions
jb .sort3 ; if they are already sorted, skip ahead (123)
xchg r10, r11 ; otherwise, swap the last pair (132->123; 231->213)
.sort3:
cmp r9, r10 ; compare first pair of dimensions again in case the smallest number started at the end and was moved to second position
jb .sortEnd ; if they are already sorted, skip ahead (123)
xchg r9, r10 ; otherwise, swap the first pair (213->123)
.sortEnd: ; at this point, the dimensions are sorted from smallest to largest in registers r9, r10, r11
mov rax, 2
mul r9
mul r10
add r12, rax ; add 2 * dim1 * dim2
mov rax, 2
mul r9
mul r11
add r12, rax ; add 2 * dim1 * dim3
mov rax, 2
mul r10
mul r11
add r12, rax ; add 2 * dim2 * dim3
mov rax, r9
mul r10
add r12, rax ; add square area of smallest side
movzx rbx, byte [ rcx ] ; read current character
cmp bl, 0 ; if we have not reached end of string yet,
jne .nextLine ; go read the next line
lea rcx, [ print_wrapping_paper ]
mov rdx, r12
call print
add rsp, 32
pop r12
pop rbx
leave
ret
.nextNumber:
xor r8, r8 ; reset return value to zero
.nextDigit:
movzx rbx, byte [ rcx ] ; read current character
inc rcx ; move to next character
cmp bl, '0'
jb .nonDigitCharacter
cmp bl, '9'
ja .nonDigitCharacter
mov rax, 10
mul r8 ; shift digit accumulator by one decimal place
mov r8, rax ; move multiplied result back to digit accumulator
sub rbx, '0' ; convert ASCII to digit
add r8, rbx ; add digit to accumulator
jmp .nextDigit
.nonDigitCharacter:
ret ; return from nextNumber calls
section .data
print_wrapping_paper: db `Wrapping paper required: %d\n`, 0

View File

@ -4,8 +4,9 @@ project(AOC)
enable_language(ASM_NASM)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX")
set(CMAKE_NASM_LINK_EXECUTABLE "ld <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CAN_USE_ASSEMBLER TRUE)
add_subdirectory(01)
add_subdirectory(02)

View File

@ -12,11 +12,9 @@ The repository contains a Gradle project (`build.gradle.kts`) that sets up every
The source code is in `main.kt`. The run configuration executes the `main()` method in this file.
## NASM x86 / x64 Assembly
## NASM x64 Assembly
The repository contains a CMake project (`CMakeLists.txt`) in the respective year's folder, which sets up every day as a CMake subproject. You should be able to load the CMake project into [CLion](https://www.jetbrains.com/clion/), as long as you have two toolchains set up:
- Visual Studio x86
- Visual Studio x64
The repository contains a CMake project (`CMakeLists.txt`) in the respective year's folder, which sets up every day as a CMake subproject. You should be able to load the CMake project into [CLion](https://www.jetbrains.com/clion/), as long as you have a toolchain named `Visual Studio x64` set to use the `amd64` architecture.
The source code is in `main.c`, which is either in the puzzle's own folder, or in `utils` if no adjustments are needed. By default, `main.c` reads the whole input file into a buffer, and passes it as a parameter to the `entryPoint` function defined in `main.asm` which implements the logic and output of each puzzle.
@ -31,7 +29,8 @@ The versions should not matter, but I used Visual Studio 2019 with `MSVC v142 (1
| Year | Day | Language |
|-----:|----:|----------|
| 2015 | 01 | NASM x86 |
| 2015 | 01 | NASM x64 |
| 2015 | 02 | NASM x64 |
| 2021 | 01 | Kotlin |
| 2021 | 02 | Kotlin |
| 2021 | 03 | Kotlin |