diff --git a/05/Makefile b/05/Makefile index 6c7e6ca..573eb71 100644 --- a/05/Makefile +++ b/05/Makefile @@ -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 diff --git a/05/main.s b/05/main.s new file mode 100644 index 0000000..8618dfc --- /dev/null +++ b/05/main.s @@ -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