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