Assembly code is really fun
This commit is contained in:
parent
7cef5d2316
commit
47c1398c6d
@ -1,6 +1,7 @@
|
||||
format ELF64 executable 3
|
||||
include "lib/linux_syscall.inc"
|
||||
include "lib/itoa.inc"
|
||||
include "lib/print.inc"
|
||||
|
||||
segment readable executable
|
||||
entry main
|
||||
@ -20,6 +21,17 @@ main:
|
||||
;; Close the input file
|
||||
close [input_fd]
|
||||
|
||||
call part_1
|
||||
|
||||
call part_2
|
||||
|
||||
;; Unmap the mapped file
|
||||
munmap [input], [file_stat.st_size]
|
||||
|
||||
;; Done!
|
||||
exit 0
|
||||
|
||||
part_1:
|
||||
;; Setup the loop variables for counting
|
||||
;; rbx starts at the first byte of input, and is incremented to read it all
|
||||
mov rbx, [input]
|
||||
@ -28,42 +40,47 @@ main:
|
||||
;; rdx counts down from the file's size to 0
|
||||
mov rdx, [file_stat.st_size]
|
||||
|
||||
lp:
|
||||
.lp:
|
||||
;; Is the current character the "go up" character?
|
||||
cmp byte [rbx], '('
|
||||
;; If so, jump to "up"
|
||||
je up
|
||||
je .up
|
||||
;; Is the current character the "go down" character?
|
||||
cmp byte [rbx], ')'
|
||||
;; If so, it's the "go down" character, so decrement the current floor
|
||||
je down
|
||||
je .down
|
||||
;; Otherwise it's the EOF probably, skip it
|
||||
jmp other
|
||||
up:
|
||||
jmp .other
|
||||
.up:
|
||||
;; We should "go up", so increment the current floor
|
||||
inc rcx
|
||||
jmp other
|
||||
down:
|
||||
jmp .other
|
||||
.down:
|
||||
;; We should "go down", so decrement the current floor
|
||||
dec rcx
|
||||
other:
|
||||
.other:
|
||||
;; Check the next character in the file
|
||||
inc rbx
|
||||
;; Count down the file's length
|
||||
dec rdx
|
||||
;; If we haven't reached the end of the file, loop
|
||||
jnz lp
|
||||
jnz .lp
|
||||
|
||||
;; Put part 1's answer in rax
|
||||
mov rax, rcx
|
||||
mov rbx, part_1
|
||||
|
||||
;; Convert rax to a c string in rbx
|
||||
mov rbx, part_1_answer
|
||||
call itoa
|
||||
|
||||
;; Write part 1's verbiage to STDOUT
|
||||
write STDOUT, part_1_verbiage, 8
|
||||
write STDOUT, part_1, 6
|
||||
write STDOUT, newline, 1
|
||||
;; Print part 1's verbiage
|
||||
mov rdi, part_1_verbiage
|
||||
call print_c_string
|
||||
call print_newline
|
||||
|
||||
ret
|
||||
|
||||
part_2:
|
||||
;; Setup the loop variables for counting
|
||||
;; rbx starts at the first byte of input, and is incremented to read it all
|
||||
mov rbx, [input]
|
||||
@ -71,44 +88,40 @@ other:
|
||||
mov rcx, 0
|
||||
;; rdx tracks how many steps we've made so far
|
||||
mov rdx, 0
|
||||
lp2:
|
||||
.lp:
|
||||
cmp byte [rbx], '('
|
||||
je up2
|
||||
je .up
|
||||
dec rcx
|
||||
jmp moved2
|
||||
up2:
|
||||
jmp .moved
|
||||
.up:
|
||||
inc rcx
|
||||
moved2:
|
||||
.moved:
|
||||
inc rdx
|
||||
cmp rcx, 0
|
||||
jl done
|
||||
jl .done
|
||||
inc rbx
|
||||
jnz lp2
|
||||
done:
|
||||
jnz .lp
|
||||
.done:
|
||||
|
||||
;; Put part 2's answer in rax
|
||||
mov rax, rdx
|
||||
mov rbx, part_2
|
||||
|
||||
;; Convert rax to a c string in rbx
|
||||
mov rbx, part_2_answer
|
||||
call itoa
|
||||
|
||||
;; Write part 2's verbiage to STDOUT
|
||||
write STDOUT, part_2_verbiage, 8
|
||||
write STDOUT, part_2, 6
|
||||
write STDOUT, newline, 1
|
||||
|
||||
;; Unmap the mapped file
|
||||
munmap [input], [file_stat.st_size]
|
||||
|
||||
;; Done!
|
||||
exit 0
|
||||
;; Print part 2's verbiage
|
||||
mov rdi, part_2_verbiage
|
||||
call print_c_string
|
||||
call print_newline
|
||||
ret
|
||||
|
||||
segment readable writable
|
||||
input_filename db '../data/2015/1/input.txt', 0
|
||||
input_fd dq -1
|
||||
input dq -1
|
||||
part_1_verbiage db 'Part 1: ', 0
|
||||
part_1 db ' ', 0
|
||||
part_2_verbiage db 'Part 2: ', 0
|
||||
part_2 db ' ', 0
|
||||
newline db 10
|
||||
part_1_verbiage db 'Part 1: '
|
||||
part_1_answer db ' ', 0
|
||||
part_2_verbiage db 'Part 2: '
|
||||
part_2_answer db ' ', 0
|
||||
file_stat s_stat
|
||||
|
@ -1,22 +1,28 @@
|
||||
format ELF64 executable 3
|
||||
include "lib/linux_syscall.inc"
|
||||
include "lib/print.inc"
|
||||
include "lib/itoa.inc"
|
||||
|
||||
segment readable executable
|
||||
entry main
|
||||
|
||||
main:
|
||||
mov rdi, input_filename
|
||||
mov rax, 42069
|
||||
mov rbx, part_1
|
||||
call itoa
|
||||
|
||||
mov rdi, part_1_verbiage
|
||||
call print_c_string
|
||||
|
||||
exit 0
|
||||
|
||||
segment readable writable
|
||||
input_filename db '../data/2015/1/input.txt', 0, 'more text', 0
|
||||
input_fd dq -1
|
||||
input dq -1
|
||||
part_1_verbiage db 'Part 1: ', 0
|
||||
part_1 db ' ', 0
|
||||
part_1_verbiage db 'Part 1: '
|
||||
part_1 db ' ', 0
|
||||
part_2_verbiage db 'Part 2: ', 0
|
||||
part_2 db ' ', 0
|
||||
part_2 db ' ', 0
|
||||
newline db 10
|
||||
file_stat s_stat
|
||||
|
@ -1,12 +1,21 @@
|
||||
;; rax contains the integer
|
||||
;; rbx contains a pointer to the string buffer
|
||||
itoa:
|
||||
;; Fill 6 digits with zeroes
|
||||
mov byte [rbx], '0'
|
||||
mov byte [rbx + 1], '0'
|
||||
mov byte [rbx + 2], '0'
|
||||
mov byte [rbx + 3], '0'
|
||||
mov byte [rbx + 4], '0'
|
||||
mov byte [rbx + 5], '0'
|
||||
|
||||
;; Special case for the number '0'
|
||||
cmp rax, 0
|
||||
jne .not_zero
|
||||
mov byte [rbx + 1], 0
|
||||
ret
|
||||
|
||||
.not_zero:
|
||||
sub rax, 100000
|
||||
inc byte [rbx]
|
||||
cmp rax, 0
|
||||
@ -42,4 +51,47 @@ itoa:
|
||||
add rax, 10
|
||||
dec byte [rbx + 4]
|
||||
add [rbx + 5], rax
|
||||
|
||||
|
||||
;; Time to shift everything left
|
||||
;; End the current string with a null byte
|
||||
mov byte [rbx + 6], 0
|
||||
.shift_left_loop:
|
||||
cmp byte [rbx], '0'
|
||||
jne .done
|
||||
|
||||
mov rcx, rbx
|
||||
inc rcx
|
||||
mov rdx, [rcx]
|
||||
and rdx, 255
|
||||
mov [rbx], dx
|
||||
|
||||
inc rcx
|
||||
mov rdx, [rcx]
|
||||
and rdx, 255
|
||||
mov [rbx + 1], dx
|
||||
|
||||
inc rcx
|
||||
mov rdx, [rcx]
|
||||
and rdx, 255
|
||||
mov [rbx + 2], dx
|
||||
|
||||
inc rcx
|
||||
mov rdx, [rcx]
|
||||
and rdx, 255
|
||||
mov [rbx + 3], dx
|
||||
|
||||
inc rcx
|
||||
mov rdx, [rcx]
|
||||
and rdx, 255
|
||||
mov [rbx + 4], dx
|
||||
|
||||
inc rcx
|
||||
mov rdx, [rcx]
|
||||
and rdx, 255
|
||||
mov [rbx + 5], dx
|
||||
|
||||
jmp .shift_left_loop
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
@ -31,3 +31,8 @@ print_c_string:
|
||||
write STDOUT, r11, r12
|
||||
|
||||
ret
|
||||
|
||||
newline db 10, 0
|
||||
print_newline:
|
||||
write STDOUT, newline, 1
|
||||
ret
|
||||
|
Loading…
Reference in New Issue
Block a user