1
0
Fork 0
Advent-of-Code/2015/02/main.asm

133 lines
3.2 KiB
NASM

bits 64
default rel
section .text
extern print
global entryPoint
entryPoint:
push rbp
mov rbp, rsp
push rbx
push r12
push r13
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
; r13 = total ribbon length required
xor rdx, rdx
xor r12, r12
xor r13, r13
.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 to wrapping paper length
mov rax, 2
mul r9
mul r11
add r12, rax ; add 2 * dim1 * dim3 to wrapping paper length
mov rax, 2
mul r10
mul r11
add r12, rax ; add 2 * dim2 * dim3 to wrapping paper length
mov rax, r9
mul r10
add r12, rax ; add square area of smallest side to wrapping paper length
add r13, r9
add r13, r9
add r13, r10
add r13, r10 ; add smallest perimeter to the ribbon length
mov rax, r9
mul r10
mul r11
add r13, rax ; add volume of the present to the ribbon length
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
lea rcx, [ print_ribbon_length ]
mov rdx, r13
call print
add rsp, 32
pop r13
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
print_ribbon_length: db `Ribbon length required: %d\n`, 0