Compare commits
No commits in common. "7a9bd95804669595848dcaea759913a69e7a030a" and "2598b444f8a99317bb6a3d7030b486c111286167" have entirely different histories.
7a9bd95804
...
2598b444f8
@ -1,3 +0,0 @@
|
|||||||
all:
|
|
||||||
nasm -g -felf32 main.s && ld -melf_i386 -g main.o
|
|
||||||
|
|
58
20/input
58
20/input
@ -1,58 +0,0 @@
|
|||||||
%cd -> jx, gh
|
|
||||||
%bk -> jp, cn
|
|
||||||
%px -> xc, hg
|
|
||||||
%tv -> gh, xl
|
|
||||||
&xc -> bm, zq, jf, hg, bd, hn
|
|
||||||
%bd -> px
|
|
||||||
&bh -> mf
|
|
||||||
%dx -> cn, rb
|
|
||||||
%vv -> pp, gh
|
|
||||||
broadcaster -> cx, zq, tv, rh
|
|
||||||
%rb -> cn, qr
|
|
||||||
&jf -> mf
|
|
||||||
%jd -> mm
|
|
||||||
%cx -> xd, cn
|
|
||||||
%zs -> cz
|
|
||||||
%hn -> bm
|
|
||||||
%xr -> bd, xc
|
|
||||||
&mf -> rx
|
|
||||||
%zq -> kg, xc
|
|
||||||
&cn -> sh, jd, cx, tc, xd
|
|
||||||
%cs -> xj
|
|
||||||
%fb -> tc, cn
|
|
||||||
%mm -> cn, bk
|
|
||||||
%sq -> th, hz
|
|
||||||
%sz -> vx
|
|
||||||
%xl -> gh, sz
|
|
||||||
%vm -> gh, vv
|
|
||||||
%jp -> cn
|
|
||||||
%qr -> cn, jd
|
|
||||||
%bq -> xc, zv
|
|
||||||
&sh -> mf
|
|
||||||
%gz -> gs, hz
|
|
||||||
%qc -> qg, xc
|
|
||||||
%hg -> bq
|
|
||||||
%dt -> sq, hz
|
|
||||||
%xj -> fz
|
|
||||||
%qs -> gh
|
|
||||||
%fz -> hz, zs
|
|
||||||
%qg -> xc
|
|
||||||
%pp -> qs, gh
|
|
||||||
%zv -> xc, qc
|
|
||||||
%rh -> hz, mr
|
|
||||||
&gh -> tv, lk, sz, bh, vx
|
|
||||||
%th -> hz
|
|
||||||
&mz -> mf
|
|
||||||
%bm -> xr
|
|
||||||
%lk -> pg
|
|
||||||
%jx -> lk, gh
|
|
||||||
&hz -> xj, cs, zs, rh, mz
|
|
||||||
%tc -> dx
|
|
||||||
%mr -> hz, gz
|
|
||||||
%xd -> jk
|
|
||||||
%pg -> vm, gh
|
|
||||||
%kg -> hn, xc
|
|
||||||
%gs -> cs, hz
|
|
||||||
%vx -> cd
|
|
||||||
%cz -> hz, dt
|
|
||||||
%jk -> cn, fb
|
|
@ -1,5 +0,0 @@
|
|||||||
broadcaster -> aa, bb, cc
|
|
||||||
%aa -> bb
|
|
||||||
%bb -> cc
|
|
||||||
%cc -> iv
|
|
||||||
&iv -> aa
|
|
@ -1,5 +0,0 @@
|
|||||||
broadcaster -> aa
|
|
||||||
%aa -> iv, cn
|
|
||||||
&iv -> bb
|
|
||||||
%bb -> cn
|
|
||||||
&cn -> ou
|
|
278
20/main.s
278
20/main.s
@ -1,278 +0,0 @@
|
|||||||
%include "utils.s"
|
|
||||||
|
|
||||||
global _start
|
|
||||||
[bits 32]
|
|
||||||
[section .text]
|
|
||||||
|
|
||||||
%define FILENAME "input"
|
|
||||||
;%define FILENAME "input_test"
|
|
||||||
;%define FILENAME "input_test2"
|
|
||||||
|
|
||||||
;%define DBG
|
|
||||||
|
|
||||||
_start:
|
|
||||||
|
|
||||||
; read in modules
|
|
||||||
; module data (16 bytes):
|
|
||||||
; 0
|
|
||||||
; bit 1: type (0: flipflop, 1: conj) bit 0: state (0: low, 1: high)
|
|
||||||
; 1 2 3 4 5 6
|
|
||||||
; destination IDX list
|
|
||||||
; 7 8 9 A B C D E F
|
|
||||||
; input states (for conj modules)
|
|
||||||
; bit 0 is remembered state, higher is index
|
|
||||||
|
|
||||||
mov esi, file
|
|
||||||
read_modules:
|
|
||||||
lodsb
|
|
||||||
cmp al, '%'
|
|
||||||
je .flipflop
|
|
||||||
cmp al, '&'
|
|
||||||
je .conjunc
|
|
||||||
; broadcaster
|
|
||||||
%ifdef DBG
|
|
||||||
mov al, 'B'
|
|
||||||
call print_char
|
|
||||||
mov al, 'R'
|
|
||||||
call print_char
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
mov ch, 1<<1
|
|
||||||
mov al, 1
|
|
||||||
%ifdef DBG
|
|
||||||
call print_hex_byte
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
mov cl, -1 ; broadcaster is special
|
|
||||||
add esi, 14
|
|
||||||
mov edi, modules+16 ; module 1 is broadcast
|
|
||||||
jmp .get_dests
|
|
||||||
.flipflop:
|
|
||||||
mov cl, 0b00 ; low, flipflop
|
|
||||||
jmp .get_idx
|
|
||||||
.conjunc:
|
|
||||||
mov cl, 0b10 ; low, conj
|
|
||||||
jmp .get_idx
|
|
||||||
.get_idx:
|
|
||||||
; get ID
|
|
||||||
lodsb
|
|
||||||
%ifdef DBG
|
|
||||||
call print_char
|
|
||||||
%endif
|
|
||||||
mov bh, al
|
|
||||||
lodsb
|
|
||||||
%ifdef DBG
|
|
||||||
call print_char
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
mov bl, al
|
|
||||||
call id_to_idx ; idx in edx
|
|
||||||
mov ch, dl
|
|
||||||
%ifdef DBG
|
|
||||||
mov al, dl
|
|
||||||
call print_hex_byte
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
shl ch, 1
|
|
||||||
shl edx, 4 ; * 16
|
|
||||||
lea edi, [modules+edx]
|
|
||||||
add esi, 4
|
|
||||||
.get_dests:
|
|
||||||
; type/state in CL
|
|
||||||
mov [edi], cl
|
|
||||||
inc edi
|
|
||||||
.next_dest:
|
|
||||||
; get dest ID
|
|
||||||
lodsb
|
|
||||||
%ifdef DBG
|
|
||||||
call print_char
|
|
||||||
%endif
|
|
||||||
mov bh, al
|
|
||||||
lodsb
|
|
||||||
%ifdef DBG
|
|
||||||
call print_char
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
mov bl, al
|
|
||||||
call id_to_idx
|
|
||||||
cmp bx, 'fm'
|
|
||||||
jne .not_rx
|
|
||||||
mov [mf_idx], dx
|
|
||||||
.not_rx:
|
|
||||||
mov al, dl
|
|
||||||
%ifdef DBG
|
|
||||||
call print_hex_byte
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
stosb
|
|
||||||
; store our idx<<1 in dest inputs
|
|
||||||
shl edx, 4 ; * 16
|
|
||||||
lea edx, [modules+edx+7]
|
|
||||||
.store_input:
|
|
||||||
cmp byte [edx], 0
|
|
||||||
jnz .check_next_input
|
|
||||||
mov byte [edx], ch
|
|
||||||
jmp .input_stored
|
|
||||||
.check_next_input:
|
|
||||||
inc edx
|
|
||||||
jmp .store_input
|
|
||||||
.input_stored:
|
|
||||||
; check if more
|
|
||||||
lodsb
|
|
||||||
cmp al, ','
|
|
||||||
jne .cont ; no more
|
|
||||||
inc esi ; space
|
|
||||||
jmp .next_dest
|
|
||||||
.cont:
|
|
||||||
%ifdef DBG
|
|
||||||
call newline
|
|
||||||
%endif
|
|
||||||
cmp esi, file.over
|
|
||||||
jb read_modules
|
|
||||||
|
|
||||||
main:
|
|
||||||
; start an iteration, broadcaster (1) sends low to everything
|
|
||||||
mov dword [queue_head], 0
|
|
||||||
mov dword [queue_tail], 2
|
|
||||||
mov word [queue], 0b10 ; low to index 1
|
|
||||||
call do_iters
|
|
||||||
inc dword [final_value]
|
|
||||||
jmp main
|
|
||||||
|
|
||||||
do_iters:
|
|
||||||
; get head of queue
|
|
||||||
mov eax, [queue_head]
|
|
||||||
mov ax, [eax+queue]
|
|
||||||
%ifdef DBG
|
|
||||||
call print_hex_word
|
|
||||||
call newline
|
|
||||||
%endif
|
|
||||||
mov cl, ah ; sender
|
|
||||||
movzx eax, al
|
|
||||||
shr eax, 1 ; get pulse
|
|
||||||
setc bl
|
|
||||||
jnc .not_high
|
|
||||||
cmp al, [mf_idx]
|
|
||||||
jne .not_high
|
|
||||||
push eax
|
|
||||||
mov al, cl
|
|
||||||
call print_hex_byte
|
|
||||||
call space
|
|
||||||
mov eax, [final_value]
|
|
||||||
call print_dec
|
|
||||||
call newline
|
|
||||||
pop eax
|
|
||||||
.not_high:
|
|
||||||
; get module
|
|
||||||
mov bh, al ; idx
|
|
||||||
shl eax, 4 ; * 16
|
|
||||||
lea edi, [modules+eax]
|
|
||||||
mov al, [edi]
|
|
||||||
cmp al, -1
|
|
||||||
je .broadcast
|
|
||||||
bt ax, 1
|
|
||||||
jc .conj
|
|
||||||
.flipflop:
|
|
||||||
; if high, do nothing
|
|
||||||
test bl, bl
|
|
||||||
jnz .cont
|
|
||||||
; if low, flip and send result
|
|
||||||
xor al, 1
|
|
||||||
bt ax, 0
|
|
||||||
setc bl
|
|
||||||
mov [edi], al
|
|
||||||
jmp add_cmds
|
|
||||||
.conj:
|
|
||||||
mov dl, 1
|
|
||||||
mov esi, 7
|
|
||||||
.check_mem:
|
|
||||||
mov al, [edi+esi]
|
|
||||||
test al, al
|
|
||||||
jz .mem_done
|
|
||||||
shr al, 1
|
|
||||||
setc dh
|
|
||||||
cmp al, cl
|
|
||||||
jne .mem_cont
|
|
||||||
shr bl, 1
|
|
||||||
setc dh
|
|
||||||
rcl al, 1
|
|
||||||
mov [edi+esi], al
|
|
||||||
.mem_cont:
|
|
||||||
and dl, dh
|
|
||||||
inc esi
|
|
||||||
cmp esi, 0xF
|
|
||||||
jbe .check_mem
|
|
||||||
.mem_done:
|
|
||||||
; send high if not all were high
|
|
||||||
xor dl, 1
|
|
||||||
mov bl, dl
|
|
||||||
jmp add_cmds
|
|
||||||
.broadcast:
|
|
||||||
jmp add_cmds ; just add commands with same pulse
|
|
||||||
.cont:
|
|
||||||
mov eax, [queue_head]
|
|
||||||
add eax, 2
|
|
||||||
and eax, 511
|
|
||||||
mov [queue_head], eax
|
|
||||||
cmp eax, [queue_tail]
|
|
||||||
jne do_iters
|
|
||||||
ret
|
|
||||||
; BH: module IDX, BL: pulse, EDI: *module
|
|
||||||
add_cmds:
|
|
||||||
mov dx, bx ; save
|
|
||||||
mov ecx, 1
|
|
||||||
.loop:
|
|
||||||
mov al, [edi+ecx]
|
|
||||||
test al, al
|
|
||||||
jz .done
|
|
||||||
mov bx, dx
|
|
||||||
shl al, 1
|
|
||||||
or bl, al
|
|
||||||
%ifdef DBG
|
|
||||||
call space
|
|
||||||
mov ax, bx
|
|
||||||
call print_hex_word
|
|
||||||
call newline
|
|
||||||
%endif
|
|
||||||
; add to queue
|
|
||||||
mov eax, [queue_tail]
|
|
||||||
mov [eax+queue], bx
|
|
||||||
add eax, 2
|
|
||||||
and eax, 511
|
|
||||||
mov [queue_tail], eax
|
|
||||||
inc ecx
|
|
||||||
cmp ecx, 6
|
|
||||||
jbe .loop
|
|
||||||
.done:
|
|
||||||
jmp do_iters.cont
|
|
||||||
|
|
||||||
; ID in BX, IDX return in EDX
|
|
||||||
id_to_idx:
|
|
||||||
xor edx, edx
|
|
||||||
.test:
|
|
||||||
cmp [module_idx_to_id+edx*2], bx
|
|
||||||
je .found
|
|
||||||
inc dx
|
|
||||||
cmp dx, [next_module_idx]
|
|
||||||
jb .test
|
|
||||||
; new ID
|
|
||||||
mov [module_idx_to_id+edx*2], bx
|
|
||||||
inc word [next_module_idx]
|
|
||||||
.found:
|
|
||||||
ret
|
|
||||||
|
|
||||||
[section .data]
|
|
||||||
final_value: dd 1
|
|
||||||
next_module_idx: dw 2 ; 1 reserved for broadcaster
|
|
||||||
mf_idx: dw 0
|
|
||||||
queue_head: dd queue
|
|
||||||
queue_tail: dd queue
|
|
||||||
file: incbin FILENAME
|
|
||||||
.over: db 0 ; EOF
|
|
||||||
|
|
||||||
[section .bss]
|
|
||||||
modules: resb 64*16
|
|
||||||
module_idx_to_id: resw 64
|
|
||||||
queue: resw 64*8
|
|
||||||
|
|
||||||
[section .rodata]
|
|
296
20/main_part1.s
296
20/main_part1.s
@ -1,296 +0,0 @@
|
|||||||
%include "utils.s"
|
|
||||||
|
|
||||||
global _start
|
|
||||||
[bits 32]
|
|
||||||
[section .text]
|
|
||||||
|
|
||||||
%define FILENAME "input"
|
|
||||||
;%define FILENAME "input_test"
|
|
||||||
;%define FILENAME "input_test2"
|
|
||||||
|
|
||||||
;%define DBG
|
|
||||||
;%define DBG_ITERS 1000
|
|
||||||
|
|
||||||
_start:
|
|
||||||
|
|
||||||
; read in modules
|
|
||||||
; module data (16 bytes):
|
|
||||||
; 0
|
|
||||||
; bit 1: type (0: flipflop, 1: conj) bit 0: state (0: low, 1: high)
|
|
||||||
; 1 2 3 4 5 6
|
|
||||||
; destination IDX list
|
|
||||||
; 7 8 9 A B C D E F
|
|
||||||
; input states (for conj modules)
|
|
||||||
; bit 0 is remembered state, higher is index
|
|
||||||
|
|
||||||
mov esi, file
|
|
||||||
read_modules:
|
|
||||||
lodsb
|
|
||||||
cmp al, '%'
|
|
||||||
je .flipflop
|
|
||||||
cmp al, '&'
|
|
||||||
je .conjunc
|
|
||||||
; broadcaster
|
|
||||||
%ifdef DBG
|
|
||||||
mov al, 'B'
|
|
||||||
call print_char
|
|
||||||
mov al, 'R'
|
|
||||||
call print_char
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
mov ch, 1<<1
|
|
||||||
mov al, 1
|
|
||||||
%ifdef DBG
|
|
||||||
call print_hex_byte
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
mov cl, -1 ; broadcaster is special
|
|
||||||
add esi, 14
|
|
||||||
mov edi, modules+16 ; module 1 is broadcast
|
|
||||||
jmp .get_dests
|
|
||||||
.flipflop:
|
|
||||||
mov cl, 0b00 ; low, flipflop
|
|
||||||
jmp .get_idx
|
|
||||||
.conjunc:
|
|
||||||
mov cl, 0b10 ; low, conj
|
|
||||||
jmp .get_idx
|
|
||||||
.get_idx:
|
|
||||||
; get ID
|
|
||||||
lodsb
|
|
||||||
%ifdef DBG
|
|
||||||
call print_char
|
|
||||||
%endif
|
|
||||||
mov bh, al
|
|
||||||
lodsb
|
|
||||||
%ifdef DBG
|
|
||||||
call print_char
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
mov bl, al
|
|
||||||
call id_to_idx ; idx in edx
|
|
||||||
mov ch, dl
|
|
||||||
%ifdef DBG
|
|
||||||
mov al, dl
|
|
||||||
call print_hex_byte
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
shl ch, 1
|
|
||||||
shl edx, 4 ; * 16
|
|
||||||
lea edi, [modules+edx]
|
|
||||||
add esi, 4
|
|
||||||
.get_dests:
|
|
||||||
; type/state in CL
|
|
||||||
mov [edi], cl
|
|
||||||
inc edi
|
|
||||||
.next_dest:
|
|
||||||
; get dest ID
|
|
||||||
lodsb
|
|
||||||
%ifdef DBG
|
|
||||||
call print_char
|
|
||||||
%endif
|
|
||||||
mov bh, al
|
|
||||||
lodsb
|
|
||||||
%ifdef DBG
|
|
||||||
call print_char
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
mov bl, al
|
|
||||||
call id_to_idx
|
|
||||||
mov al, dl
|
|
||||||
%ifdef DBG
|
|
||||||
call print_hex_byte
|
|
||||||
call space
|
|
||||||
%endif
|
|
||||||
stosb
|
|
||||||
; store our idx<<1 in dest inputs
|
|
||||||
shl edx, 4 ; * 16
|
|
||||||
lea edx, [modules+edx+7]
|
|
||||||
.store_input:
|
|
||||||
cmp byte [edx], 0
|
|
||||||
jnz .check_next_input
|
|
||||||
mov byte [edx], ch
|
|
||||||
jmp .input_stored
|
|
||||||
.check_next_input:
|
|
||||||
inc edx
|
|
||||||
jmp .store_input
|
|
||||||
.input_stored:
|
|
||||||
; check if more
|
|
||||||
lodsb
|
|
||||||
cmp al, ','
|
|
||||||
jne .cont ; no more
|
|
||||||
inc esi ; space
|
|
||||||
jmp .next_dest
|
|
||||||
.cont:
|
|
||||||
%ifdef DBG
|
|
||||||
call newline
|
|
||||||
%endif
|
|
||||||
cmp esi, file.over
|
|
||||||
jb read_modules
|
|
||||||
|
|
||||||
main:
|
|
||||||
mov ecx, 1000
|
|
||||||
%ifdef DBG
|
|
||||||
mov ecx, DBG_ITERS
|
|
||||||
%endif
|
|
||||||
.loop:
|
|
||||||
push ecx
|
|
||||||
; start an iteration, broadcaster (1) sends low to everything
|
|
||||||
mov dword [queue_head], 0
|
|
||||||
mov dword [queue_tail], 2
|
|
||||||
mov word [queue], 0b10 ; low to index 1
|
|
||||||
call do_iters
|
|
||||||
pop ecx
|
|
||||||
loop .loop
|
|
||||||
jmp game_over
|
|
||||||
|
|
||||||
do_iters:
|
|
||||||
; get head of queue
|
|
||||||
mov eax, [queue_head]
|
|
||||||
mov ax, [eax+queue]
|
|
||||||
%ifdef DBG
|
|
||||||
call print_hex_word
|
|
||||||
call newline
|
|
||||||
%endif
|
|
||||||
mov cl, ah ; sender
|
|
||||||
movzx eax, al
|
|
||||||
shr eax, 1 ; get pulse
|
|
||||||
setc bl
|
|
||||||
jc .got_high
|
|
||||||
inc dword [low_count]
|
|
||||||
jmp .add_done
|
|
||||||
.got_high:
|
|
||||||
inc dword [high_count]
|
|
||||||
.add_done:
|
|
||||||
; get module
|
|
||||||
mov bh, al ; idx
|
|
||||||
shl eax, 4 ; * 16
|
|
||||||
lea edi, [modules+eax]
|
|
||||||
mov al, [edi]
|
|
||||||
cmp al, -1
|
|
||||||
je .broadcast
|
|
||||||
bt ax, 1
|
|
||||||
jc .conj
|
|
||||||
.flipflop:
|
|
||||||
; if high, do nothing
|
|
||||||
test bl, bl
|
|
||||||
jnz .cont
|
|
||||||
; if low, flip and send result
|
|
||||||
xor al, 1
|
|
||||||
bt ax, 0
|
|
||||||
setc bl
|
|
||||||
mov [edi], al
|
|
||||||
jmp add_cmds
|
|
||||||
.conj:
|
|
||||||
mov dl, 1
|
|
||||||
mov esi, 7
|
|
||||||
.check_mem:
|
|
||||||
mov al, [edi+esi]
|
|
||||||
test al, al
|
|
||||||
jz .mem_done
|
|
||||||
shr al, 1
|
|
||||||
setc dh
|
|
||||||
cmp al, cl
|
|
||||||
jne .mem_cont
|
|
||||||
shr bl, 1
|
|
||||||
setc dh
|
|
||||||
rcl al, 1
|
|
||||||
mov [edi+esi], al
|
|
||||||
.mem_cont:
|
|
||||||
and dl, dh
|
|
||||||
inc esi
|
|
||||||
cmp esi, 0xF
|
|
||||||
jbe .check_mem
|
|
||||||
.mem_done:
|
|
||||||
; send high if not all were high
|
|
||||||
xor dl, 1
|
|
||||||
mov bl, dl
|
|
||||||
jmp add_cmds
|
|
||||||
.broadcast:
|
|
||||||
jmp add_cmds ; just add commands with same pulse
|
|
||||||
.cont:
|
|
||||||
mov eax, [queue_head]
|
|
||||||
add eax, 2
|
|
||||||
and eax, 511
|
|
||||||
mov [queue_head], eax
|
|
||||||
cmp eax, [queue_tail]
|
|
||||||
jne do_iters
|
|
||||||
ret
|
|
||||||
; BH: module IDX, BL: pulse, EDI: *module
|
|
||||||
add_cmds:
|
|
||||||
mov dx, bx ; save
|
|
||||||
mov ecx, 1
|
|
||||||
.loop:
|
|
||||||
mov al, [edi+ecx]
|
|
||||||
test al, al
|
|
||||||
jz .done
|
|
||||||
mov bx, dx
|
|
||||||
shl al, 1
|
|
||||||
or bl, al
|
|
||||||
%ifdef DBG
|
|
||||||
call space
|
|
||||||
mov ax, bx
|
|
||||||
call print_hex_word
|
|
||||||
call newline
|
|
||||||
%endif
|
|
||||||
; add to queue
|
|
||||||
mov eax, [queue_tail]
|
|
||||||
mov [eax+queue], bx
|
|
||||||
add eax, 2
|
|
||||||
and eax, 511
|
|
||||||
mov [queue_tail], eax
|
|
||||||
inc ecx
|
|
||||||
cmp ecx, 6
|
|
||||||
jbe .loop
|
|
||||||
.done:
|
|
||||||
jmp do_iters.cont
|
|
||||||
|
|
||||||
game_over:
|
|
||||||
mov eax, [low_count]
|
|
||||||
call print_dec
|
|
||||||
call space
|
|
||||||
mov eax, [high_count]
|
|
||||||
call print_dec
|
|
||||||
call newline
|
|
||||||
p_string info
|
|
||||||
mul dword [low_count]
|
|
||||||
call print_dec
|
|
||||||
mov al, ':'
|
|
||||||
call print_char
|
|
||||||
mov eax, edx
|
|
||||||
call print_dec
|
|
||||||
call newline
|
|
||||||
jmp exit
|
|
||||||
|
|
||||||
; ID in BX, IDX return in EDX
|
|
||||||
id_to_idx:
|
|
||||||
xor edx, edx
|
|
||||||
.test:
|
|
||||||
cmp [module_idx_to_id+edx*2], bx
|
|
||||||
je .found
|
|
||||||
inc dx
|
|
||||||
cmp dx, [next_module_idx]
|
|
||||||
jb .test
|
|
||||||
; new ID
|
|
||||||
mov [module_idx_to_id+edx*2], bx
|
|
||||||
inc word [next_module_idx]
|
|
||||||
.found:
|
|
||||||
ret
|
|
||||||
|
|
||||||
[section .data]
|
|
||||||
low_count: dd 0
|
|
||||||
high_count: dd 0
|
|
||||||
next_module_idx: dw 2 ; 1 reserved for broadcaster
|
|
||||||
in_idx: dw 0
|
|
||||||
queue_head: dd queue
|
|
||||||
queue_tail: dd queue
|
|
||||||
file: incbin FILENAME
|
|
||||||
.over: db 0 ; EOF
|
|
||||||
|
|
||||||
[section .bss]
|
|
||||||
modules: resb 64*16
|
|
||||||
module_idx_to_id: resw 64
|
|
||||||
queue: resw 64*8
|
|
||||||
|
|
||||||
[section .rodata]
|
|
||||||
info: db `LOW:HIGH\n`
|
|
||||||
.over:
|
|
336
20/utils.s
336
20/utils.s
@ -1,336 +0,0 @@
|
|||||||
[bits 32]
|
|
||||||
[section .text]
|
|
||||||
; call # val val2
|
|
||||||
; int $0x80 eax eax edx -
|
|
||||||
;
|
|
||||||
; arg1 arg2 arg3 arg4 arg5 arg6 arg7
|
|
||||||
; ebx ecx edx esi edi ebp -
|
|
||||||
|
|
||||||
exit:
|
|
||||||
mov eax, 1 ; exit
|
|
||||||
int 0x80
|
|
||||||
|
|
||||||
; filename in EBX
|
|
||||||
; return handle in EBX
|
|
||||||
; read only
|
|
||||||
open_file:
|
|
||||||
push eax
|
|
||||||
push ecx
|
|
||||||
mov eax, 5 ; open
|
|
||||||
xor ecx, ecx ; read only
|
|
||||||
int 0x80
|
|
||||||
mov ebx, eax
|
|
||||||
pop ecx
|
|
||||||
pop eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
; file handle in EBX
|
|
||||||
; buffer in ECX
|
|
||||||
; count of bytes to read in EDX
|
|
||||||
; return bytes actually read in EAX
|
|
||||||
; exits on error
|
|
||||||
read_file:
|
|
||||||
mov eax, 3 ; read
|
|
||||||
int 0x80
|
|
||||||
test eax, eax
|
|
||||||
js .err
|
|
||||||
ret
|
|
||||||
.err:
|
|
||||||
mov eax, 4 ; write
|
|
||||||
mov ebx, 1 ; stdout
|
|
||||||
mov ecx, .err_str
|
|
||||||
mov edx, 21
|
|
||||||
int 0x80
|
|
||||||
jmp exit
|
|
||||||
.err_str: db `Could not read file.\n`
|
|
||||||
|
|
||||||
; string input in ESI
|
|
||||||
; value in EAX
|
|
||||||
; CF set if none, clear if some
|
|
||||||
; ESI set past checked area
|
|
||||||
dec_parse:
|
|
||||||
push ebx
|
|
||||||
push edx
|
|
||||||
push edi
|
|
||||||
xor eax, eax
|
|
||||||
xor edi, edi
|
|
||||||
mov ebx, 10 ; base
|
|
||||||
lodsb
|
|
||||||
sub al, '0'
|
|
||||||
js .no_input
|
|
||||||
cmp al, 9
|
|
||||||
jle .got_char
|
|
||||||
.no_input:
|
|
||||||
stc ; set CF
|
|
||||||
jmp .done
|
|
||||||
.loop:
|
|
||||||
xor eax,eax
|
|
||||||
lodsb
|
|
||||||
sub al, '0'
|
|
||||||
js .dec_done
|
|
||||||
cmp al, 9
|
|
||||||
jg .dec_done
|
|
||||||
.got_char:
|
|
||||||
xchg edi,eax
|
|
||||||
mul ebx
|
|
||||||
add edi,eax
|
|
||||||
jmp .loop
|
|
||||||
.dec_done:
|
|
||||||
clc ; clear CF
|
|
||||||
.done:
|
|
||||||
mov eax,edi
|
|
||||||
pop edi
|
|
||||||
pop edx
|
|
||||||
pop ebx
|
|
||||||
ret
|
|
||||||
|
|
||||||
; string input in ESI
|
|
||||||
; value in EAX
|
|
||||||
; CF set if none, clear if some
|
|
||||||
; ESI set past checked area
|
|
||||||
sign_dec_parse:
|
|
||||||
push ebx
|
|
||||||
push ecx
|
|
||||||
push edx
|
|
||||||
push edi
|
|
||||||
xor eax, eax
|
|
||||||
xor edi, edi
|
|
||||||
xor ecx, ecx ; neg flag
|
|
||||||
mov ebx, 10 ; base
|
|
||||||
cmp byte [esi], '-'
|
|
||||||
jne .no_minus
|
|
||||||
inc esi
|
|
||||||
mov cl, 1
|
|
||||||
.no_minus:
|
|
||||||
lodsb
|
|
||||||
sub al, '0'
|
|
||||||
js .no_input
|
|
||||||
cmp al, 9
|
|
||||||
jle .got_char
|
|
||||||
.no_input:
|
|
||||||
stc ; set CF
|
|
||||||
jmp .done
|
|
||||||
.loop:
|
|
||||||
xor eax,eax
|
|
||||||
lodsb
|
|
||||||
sub al, '0'
|
|
||||||
js .dec_done
|
|
||||||
cmp al, 9
|
|
||||||
jg .dec_done
|
|
||||||
.got_char:
|
|
||||||
xchg edi,eax
|
|
||||||
mul ebx
|
|
||||||
add edi,eax
|
|
||||||
jmp .loop
|
|
||||||
.dec_done:
|
|
||||||
test ecx, ecx
|
|
||||||
jz .not_neg
|
|
||||||
neg edi
|
|
||||||
.not_neg:
|
|
||||||
clc ; clear CF
|
|
||||||
.done:
|
|
||||||
mov eax,edi
|
|
||||||
pop edi
|
|
||||||
pop edx
|
|
||||||
pop ecx
|
|
||||||
pop ebx
|
|
||||||
ret
|
|
||||||
|
|
||||||
; modifies no regs
|
|
||||||
newline:
|
|
||||||
pushad
|
|
||||||
push 10
|
|
||||||
mov eax, 4 ; write
|
|
||||||
mov ebx, 1 ; stdout
|
|
||||||
mov ecx, esp ; string
|
|
||||||
mov edx, 1 ; length
|
|
||||||
int 0x80
|
|
||||||
add esp, 4
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
; modifies no regs
|
|
||||||
space:
|
|
||||||
pushad
|
|
||||||
push 9
|
|
||||||
mov eax, 4 ; write
|
|
||||||
mov ebx, 1 ; stdout
|
|
||||||
mov ecx, esp ; string
|
|
||||||
mov edx, 1 ; length
|
|
||||||
int 0x80
|
|
||||||
add esp, 4
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
|
|
||||||
; input in EAX, all regs unmodified
|
|
||||||
print_dec:
|
|
||||||
pushad ; save regs
|
|
||||||
; max 4294967296 is 10 chars
|
|
||||||
; round to nearest 32-bit boundary
|
|
||||||
sub esp, 12
|
|
||||||
; string in ECX, length in EDX
|
|
||||||
lea ecx, [esp+11] ; last possible byte
|
|
||||||
; check for 0
|
|
||||||
test eax, eax
|
|
||||||
jz .zero
|
|
||||||
mov ebx, 10 ; base 10
|
|
||||||
xor esi, esi ; counter
|
|
||||||
.div_shit:
|
|
||||||
xor edx, edx
|
|
||||||
; divide
|
|
||||||
div ebx
|
|
||||||
dec ecx ; next char
|
|
||||||
inc esi
|
|
||||||
; store
|
|
||||||
add dl, '0'
|
|
||||||
mov byte [ecx], dl
|
|
||||||
; check if done
|
|
||||||
test eax, eax
|
|
||||||
jnz .div_shit ; continue
|
|
||||||
mov edx, esi ; counter in edx
|
|
||||||
jmp .write
|
|
||||||
.zero:
|
|
||||||
mov byte [ecx], '0'
|
|
||||||
mov edx, 1 ; length
|
|
||||||
.write:
|
|
||||||
mov eax, 4 ; write
|
|
||||||
mov ebx, 1 ; stdout
|
|
||||||
int 0x80
|
|
||||||
add esp, 12 ; restore stack
|
|
||||||
popad ; restore regs
|
|
||||||
ret
|
|
||||||
|
|
||||||
; input in EAX, all regs unmodified
|
|
||||||
print_sign_dec:
|
|
||||||
pushad ; save regs
|
|
||||||
; range -2147483648 to 2147483647 is 11 chars
|
|
||||||
; round to nearest 32-bit boundary
|
|
||||||
sub esp, 12
|
|
||||||
; string in ECX, length in EDX
|
|
||||||
lea ecx, [esp+11] ; last possible byte
|
|
||||||
; check for 0, negative
|
|
||||||
xor ebp, ebp
|
|
||||||
test eax, eax
|
|
||||||
jz .zero
|
|
||||||
jns .positive
|
|
||||||
neg eax
|
|
||||||
mov ebp, 1
|
|
||||||
.positive:
|
|
||||||
mov ebx, 10 ; base 10
|
|
||||||
xor esi, esi ; counter
|
|
||||||
.div_shit:
|
|
||||||
xor edx, edx
|
|
||||||
; divide
|
|
||||||
div ebx
|
|
||||||
dec ecx ; next char
|
|
||||||
inc esi
|
|
||||||
; store
|
|
||||||
add dl, '0'
|
|
||||||
mov byte [ecx], dl
|
|
||||||
; check if done
|
|
||||||
test eax, eax
|
|
||||||
jnz .div_shit ; continue
|
|
||||||
mov edx, esi ; counter in edx
|
|
||||||
jmp .write
|
|
||||||
.zero:
|
|
||||||
mov byte [ecx], '0'
|
|
||||||
mov edx, 1 ; length
|
|
||||||
.write:
|
|
||||||
test ebp, ebp
|
|
||||||
jz .no_minus
|
|
||||||
dec ecx
|
|
||||||
inc edx
|
|
||||||
mov byte [ecx], '-'
|
|
||||||
.no_minus:
|
|
||||||
mov eax, 4 ; write
|
|
||||||
mov ebx, 1 ; stdout
|
|
||||||
int 0x80
|
|
||||||
add esp, 12 ; restore stack
|
|
||||||
popad ; restore regs
|
|
||||||
ret
|
|
||||||
|
|
||||||
; input in EAX, all regs unmodified
|
|
||||||
print_hex:
|
|
||||||
pushad
|
|
||||||
mov ebx, eax
|
|
||||||
shr eax, 16
|
|
||||||
call print_hex_word
|
|
||||||
mov eax, ebx
|
|
||||||
call print_hex_word
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
|
|
||||||
; input in AX, all regs unmodified
|
|
||||||
print_hex_word:
|
|
||||||
pushad
|
|
||||||
mov bx, ax
|
|
||||||
mov al, ah
|
|
||||||
call print_hex_byte
|
|
||||||
mov ax, bx
|
|
||||||
call print_hex_byte
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
|
|
||||||
; input in AL, all regs unmodified
|
|
||||||
print_hex_byte:
|
|
||||||
pushad
|
|
||||||
push '0000'
|
|
||||||
mov bl, al
|
|
||||||
shr bl, 4
|
|
||||||
mov dx, '0'
|
|
||||||
mov cx, 'A' - 10
|
|
||||||
cmp bl, 9
|
|
||||||
cmovg dx, cx
|
|
||||||
add bl, dl
|
|
||||||
mov [esp], bl
|
|
||||||
mov bl, al
|
|
||||||
and bl, 0xF
|
|
||||||
mov dx, '0'
|
|
||||||
mov cx, 'A' - 10
|
|
||||||
cmp bl, 9
|
|
||||||
cmovg dx, cx
|
|
||||||
add bl, dl
|
|
||||||
mov [esp+1], bl
|
|
||||||
mov eax, 4 ; write
|
|
||||||
mov ebx, 1 ; stdout
|
|
||||||
mov edx, 2 ; length
|
|
||||||
mov ecx, esp ; string
|
|
||||||
int 0x80
|
|
||||||
add esp, 4
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
|
|
||||||
; input in ESI, len in ECX, all regs unmodified
|
|
||||||
print_string:
|
|
||||||
pushad ; save regs
|
|
||||||
mov eax, 4 ; write
|
|
||||||
mov ebx, 1 ; stdout
|
|
||||||
mov edx, ecx ; length
|
|
||||||
mov ecx, esi ; string
|
|
||||||
int 0x80
|
|
||||||
popad ; restore regs
|
|
||||||
ret
|
|
||||||
|
|
||||||
; input in AL, all regs unmodified
|
|
||||||
print_char:
|
|
||||||
pushad ; save regs
|
|
||||||
push eax
|
|
||||||
mov eax, 4 ; write
|
|
||||||
mov ebx, 1 ; stdout
|
|
||||||
mov edx, 1 ; length
|
|
||||||
mov ecx, esp ; string
|
|
||||||
int 0x80
|
|
||||||
add esp, 4
|
|
||||||
popad ; restore regs
|
|
||||||
ret
|
|
||||||
|
|
||||||
; --- MACROS ---
|
|
||||||
%define len(x) x %+ .over - x
|
|
||||||
%macro p_string 1
|
|
||||||
push esi
|
|
||||||
push ecx
|
|
||||||
mov esi, %1
|
|
||||||
mov ecx, len(%1)
|
|
||||||
call print_string
|
|
||||||
pop ecx
|
|
||||||
pop esi
|
|
||||||
%endmacro
|
|
Loading…
Reference in New Issue
Block a user