day 5 part 2
This commit is contained in:
parent
a9c2b24f9c
commit
232bea8dec
@ -1,3 +1,3 @@
|
||||
all:
|
||||
nasm -felf32 main.s && ld -melf_i386 main.o
|
||||
nasm -g -felf32 main.s && ld -melf_i386 -g main.o
|
||||
|
||||
|
414
05/main.s
Normal file
414
05/main.s
Normal file
@ -0,0 +1,414 @@
|
||||
%define BUFF_LIM 32768
|
||||
|
||||
global _start
|
||||
[bits 32]
|
||||
[section .text]
|
||||
|
||||
%include "utils.s"
|
||||
|
||||
_start:
|
||||
mov ebx, filename
|
||||
call open_file
|
||||
mov ecx, read_buff
|
||||
mov edx, BUFF_LIM
|
||||
call read_file
|
||||
add eax, read_buff
|
||||
mov [file_lim], eax
|
||||
|
||||
; skip until :
|
||||
; loop until :
|
||||
; get next number
|
||||
; save in seeds@seedcnt
|
||||
; increment seedcnt
|
||||
; end
|
||||
;
|
||||
; get the map tables
|
||||
; current_map := 0
|
||||
; do 7 times
|
||||
; loop until :
|
||||
; get next number
|
||||
; save in tmp
|
||||
; get next number
|
||||
; save in ((maps@current_map)@current_line)+4 SRC
|
||||
; get next number
|
||||
; save in ((maps@current_map)@current_line)+8 RNG
|
||||
; tmp := tmp - SRC
|
||||
; changes DEST to represent *change* in location
|
||||
; save in ((maps@current_map)@current_line)+0 DEST
|
||||
; end
|
||||
; end
|
||||
;
|
||||
; for (seed,srng) in seeds
|
||||
; list_bs@0 := (seed,srng,0)
|
||||
; listcnt := 1
|
||||
; for m in maps
|
||||
; for (d,s,r) in m
|
||||
; listi := 0
|
||||
; maxs := s + r - 1
|
||||
; while listi < listcnt
|
||||
; (is, ir, mod) := list_bs@listi
|
||||
; if mod is map .cont
|
||||
; maxi := is + ir - 1
|
||||
; if maxi < s .cont
|
||||
; if is > maxs .cont
|
||||
; fr := greater(is, s)
|
||||
; lr := less(maxi, maxs)
|
||||
; rr := lr - fr + 1
|
||||
; .chk_AE:
|
||||
; if is < fr
|
||||
; (list_bs@listi).r := fr - is
|
||||
; NEWENT(fr + d, rr, map)
|
||||
; else
|
||||
; (list_bs@listi).s := fr + d
|
||||
; (list_bs@listi).r := rr
|
||||
; (list_bs@listi).mod := map
|
||||
; end
|
||||
; .chk_AF:
|
||||
; if imax > lr
|
||||
; NEWENT(lr + 1, imax - lr, mod)
|
||||
; end
|
||||
; .cont: inc listi
|
||||
; end
|
||||
; end
|
||||
; end
|
||||
; find smallest
|
||||
; tmp := final_value
|
||||
; for (is, _, _) in list_bs
|
||||
; if is < tmp then tmp := is
|
||||
; end
|
||||
; final_value := tmp
|
||||
; end
|
||||
; output final_value
|
||||
|
||||
|
||||
; skip until :
|
||||
mov esi, read_buff
|
||||
skip_to_nums:
|
||||
lodsb
|
||||
cmp al, ':'
|
||||
jne skip_to_nums
|
||||
|
||||
; loop until :
|
||||
; get next number
|
||||
; save in seeds@seedcnt
|
||||
; increment seedcnt
|
||||
; end
|
||||
inc esi
|
||||
xor ebx, ebx ; seedcnt
|
||||
get_seeds:
|
||||
cmp byte [esi-1], ':'
|
||||
je .got_seeds
|
||||
call dec_parse
|
||||
jc get_seeds
|
||||
; save number
|
||||
mov [seeds+ebx*4], eax
|
||||
inc ebx
|
||||
jmp get_seeds
|
||||
.got_seeds:
|
||||
mov [seedcnt], ebx
|
||||
inc esi ; don't retrigger : check
|
||||
|
||||
; get the map tables
|
||||
; current_map := 0
|
||||
mov dword [current_map], 0
|
||||
; do 7 times
|
||||
; ...
|
||||
; end
|
||||
mov ecx, 7
|
||||
process_maps:
|
||||
push ecx
|
||||
|
||||
; loop until :
|
||||
; ...
|
||||
; end
|
||||
mov edi, [current_map]
|
||||
mov edi, [maps+edi*4]
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
map_chk:
|
||||
; get next number
|
||||
; save in tmp
|
||||
; get next number
|
||||
; save in ((maps@current_map)@current_line)+4 SRC
|
||||
; get next number
|
||||
; save in ((maps@current_map)@current_line)+8 RNG
|
||||
; tmp := tmp - SRC
|
||||
; changes DEST to represent *change* in location
|
||||
; save in ((maps@current_map)@current_line)+0 DEST
|
||||
|
||||
.get_dest:
|
||||
cmp byte [esi-1], ':' ; make sure we aren't passing into new map
|
||||
je .map_done
|
||||
call dec_parse
|
||||
jc .get_dest
|
||||
; save in tmp
|
||||
mov ebx, eax
|
||||
.get_src:
|
||||
call dec_parse
|
||||
jc .get_src
|
||||
; save in ((maps@current_map)@current_line)+4 SRC
|
||||
mov ecx, eax
|
||||
.get_rng:
|
||||
call dec_parse
|
||||
jc .get_rng
|
||||
; save in ((maps@current_map)@current_line)+8 RNG
|
||||
mov edx, eax
|
||||
; tmp := tmp - SRC
|
||||
; changes DEST to represent *change* in location
|
||||
; save in ((maps@current_map)@current_line)+0 DEST
|
||||
sub ebx, ecx
|
||||
mov eax, ebx
|
||||
stosd
|
||||
mov eax, ecx
|
||||
stosd
|
||||
mov eax, edx
|
||||
stosd
|
||||
jmp map_chk
|
||||
.map_done:
|
||||
inc dword [current_map]
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
|
||||
; process_maps loop
|
||||
inc esi ; skip ':'
|
||||
pop ecx
|
||||
dec ecx
|
||||
test ecx, ecx
|
||||
jnz process_maps
|
||||
|
||||
; debug print maps
|
||||
;mov ecx, 0
|
||||
;dbg_maps:
|
||||
;push ecx
|
||||
;mov esi, [maps+ecx*4]
|
||||
;.lines:
|
||||
;xor ebx, ebx
|
||||
;lodsd
|
||||
;add ebx, eax
|
||||
;call print_dec
|
||||
;call space
|
||||
;lodsd
|
||||
;add ebx, eax
|
||||
;call print_dec
|
||||
;call space
|
||||
;lodsd
|
||||
;add ebx, eax
|
||||
;call print_dec
|
||||
;call newline
|
||||
;test ebx, ebx
|
||||
;jnz .lines
|
||||
;call newline
|
||||
;inc ecx
|
||||
;cmp ecx, 7
|
||||
;jb dbg_maps
|
||||
|
||||
|
||||
; for (seed,srng) in seeds
|
||||
mov eax, [seedcnt]
|
||||
shr eax, 1
|
||||
mov esi, seeds
|
||||
for_seeds:
|
||||
push eax ; seed count
|
||||
; list_bs@0 := (seed,srng,0)
|
||||
; listcnt := 1
|
||||
mov edi, list_bs
|
||||
movsd ; seed
|
||||
movsd ; srng
|
||||
push esi ; seed ptr
|
||||
xor eax, eax
|
||||
stosd ; mod
|
||||
mov dword [listcnt], 1
|
||||
|
||||
; for m in maps
|
||||
mov ecx, 0
|
||||
for_maps:
|
||||
mov ebp, [maps+ecx*4] ; map
|
||||
push ecx ; map idx
|
||||
|
||||
; for line in m
|
||||
mov esi, ebp ; line := map@0
|
||||
sub esp, 32 ; space for 0 ?, 4 ?, 8 map, 12 mod, 16 d, 20 r, 24 lineptr, 28 list counter
|
||||
for_lines:
|
||||
lodsd
|
||||
mov [esp+16], eax ; d
|
||||
lodsd
|
||||
mov edx, eax ; s
|
||||
lodsd
|
||||
mov [esp+20], eax ; r
|
||||
test eax, eax
|
||||
jz for_lines_end ; null entry - we're done
|
||||
mov [esp+24], esi ; lineptr
|
||||
|
||||
; maxs := s + r - 1
|
||||
mov edi, [esp+20]
|
||||
add edi, edx
|
||||
dec edi
|
||||
|
||||
; for i in listcnt
|
||||
mov eax, [listcnt]
|
||||
mov [esp+28], eax
|
||||
mov esi, list_bs
|
||||
for_in_list:
|
||||
lodsd
|
||||
mov ecx, eax ; is
|
||||
lodsd
|
||||
mov ebx, eax ; ir
|
||||
lodsd ; mod
|
||||
; if mod is map continue
|
||||
cmp eax, ebp
|
||||
je for_in_list_cont
|
||||
; maxi := is + ir - 1
|
||||
add ebx, ecx ; maxi, ir not needed anymore
|
||||
dec ebx
|
||||
; if maxi < s .cont
|
||||
; if is > maxs .cont
|
||||
cmp ebx, edx
|
||||
jb for_in_list_cont
|
||||
cmp ecx, edi
|
||||
ja for_in_list_cont
|
||||
; make space
|
||||
mov [esp], edi ; maxs
|
||||
mov [esp+4], edx ; s
|
||||
mov [esp+8], ebp ; map
|
||||
mov [esp+12],eax ; mod
|
||||
; fr := greater(is, s)
|
||||
; lr := less(maxi, maxs)
|
||||
; rr := lr - fr + 1
|
||||
cmp ecx, edx
|
||||
cmova edx, ecx ; edx: fr
|
||||
cmp ebx, edi
|
||||
cmovb edi, ebx ; edi: lr
|
||||
|
||||
.chk_AE:
|
||||
; if is < fr
|
||||
cmp ecx, edx
|
||||
jae .chk_AE_else
|
||||
; (list_bs@listi).r := fr - is
|
||||
mov eax, edx
|
||||
sub eax, ecx
|
||||
mov [esi-8], eax
|
||||
; NEWENT(fr + d, rr, map)
|
||||
mov eax, [listcnt]
|
||||
shl eax, 1
|
||||
add eax, [listcnt]
|
||||
lea eax, [list_bs+eax*4]
|
||||
mov [eax+8], ebp ; map
|
||||
mov ebp, edi
|
||||
sub ebp, edx
|
||||
inc ebp
|
||||
mov [eax+4], ebp ; rr
|
||||
add edx, [esp+16]
|
||||
mov [eax], edx ; fr + d
|
||||
inc dword [listcnt]
|
||||
jmp .chk_AF
|
||||
.chk_AE_else:
|
||||
; else
|
||||
; (list_bs@listi).mod := map
|
||||
mov [esi-4], ebp
|
||||
; (list_bs@listi).r := rr
|
||||
mov eax, edi
|
||||
sub eax, edx
|
||||
inc eax
|
||||
mov [esi-8], eax
|
||||
; (list_bs@listi).s := fr + d
|
||||
add edx, [esp+16]
|
||||
mov [esi-12], edx ; d
|
||||
|
||||
.chk_AF:
|
||||
; if imax > lr
|
||||
cmp ebx, edi
|
||||
jbe .chk_AF_not
|
||||
; NEWENT(lr + 1, maxi - lr, mod)
|
||||
mov eax, [listcnt]
|
||||
shl eax, 1
|
||||
add eax, [listcnt]
|
||||
lea eax, [list_bs+eax*4]
|
||||
mov edx, [esp+12]
|
||||
mov [eax+8], edx ; mod
|
||||
sub ebx, edi
|
||||
mov [eax+4], ebx ; maxi - lr
|
||||
inc edi
|
||||
mov [eax], edi ; lr + 1
|
||||
inc dword [listcnt]
|
||||
.chk_AF_not:
|
||||
|
||||
; restore
|
||||
mov edi, [esp] ; maxs
|
||||
mov edx, [esp+4] ; s
|
||||
mov ebp, [esp+8] ; map
|
||||
mov eax, [esp+12] ; mod
|
||||
for_in_list_cont:
|
||||
sub dword [esp+28], 1 ; check if done
|
||||
jnz for_in_list
|
||||
; end
|
||||
|
||||
for_lines_cont:
|
||||
mov esi, [esp+24] ; lineptr
|
||||
jmp for_lines
|
||||
|
||||
for_lines_end:
|
||||
add esp, 32 ; restore stack
|
||||
; end
|
||||
|
||||
for_maps_cont:
|
||||
pop ecx ; map idx
|
||||
inc ecx
|
||||
cmp ecx, 7
|
||||
jl for_maps
|
||||
; end
|
||||
|
||||
; find smallest
|
||||
; tmp := final_value
|
||||
; for (is, _, _) in list_bs
|
||||
; if is < tmp then tmp := is
|
||||
; end
|
||||
; final_value := tmp
|
||||
mov ebx, [final_value]
|
||||
mov ecx, [listcnt]
|
||||
mov esi, list_bs
|
||||
find_smallest:
|
||||
lodsd
|
||||
cmp eax, ebx
|
||||
cmovb ebx, eax
|
||||
add esi, 8
|
||||
loop find_smallest
|
||||
mov [final_value], ebx
|
||||
|
||||
for_seeds_cont:
|
||||
pop esi ; seed ptr
|
||||
pop eax ; seed count
|
||||
sub eax, 1
|
||||
jnz for_seeds ; loop if not finished
|
||||
; end
|
||||
; done processing... at last
|
||||
|
||||
|
||||
;output tmp
|
||||
mov eax, [final_value]
|
||||
call print_dec
|
||||
|
||||
game_over:
|
||||
jmp exit
|
||||
|
||||
[section .data]
|
||||
file_lim: dd 0
|
||||
final_value: dd 0xffffffff
|
||||
maps: dd seedsoil, soilfert, fertwater, waterlight, lighttemp, temphumid, humidloc
|
||||
current_map: dd 0
|
||||
filename: db "input",0
|
||||
|
||||
[section .bss]
|
||||
seedcnt: resd 1
|
||||
seeds: resd 64
|
||||
seedsoil: resd 64*3
|
||||
soilfert: resd 64*3
|
||||
fertwater: resd 64*3
|
||||
waterlight: resd 64*3
|
||||
lighttemp: resd 64*3
|
||||
temphumid: resd 64*3
|
||||
humidloc: resd 64*3
|
||||
read_buff: resb BUFF_LIM
|
||||
listcnt: resd 1
|
||||
list_bs: resb 2000000000
|
Loading…
Reference in New Issue
Block a user