day 20 part 1
This commit is contained in:
parent
2598b444f8
commit
9f5df0a65c
3
20/Makefile
Normal file
3
20/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
all:
|
||||||
|
nasm -g -felf32 main.s && ld -melf_i386 -g main.o
|
||||||
|
|
58
20/input
Normal file
58
20/input
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
%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
|
5
20/input_test
Normal file
5
20/input_test
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
broadcaster -> aa, bb, cc
|
||||||
|
%aa -> bb
|
||||||
|
%bb -> cc
|
||||||
|
%cc -> iv
|
||||||
|
&iv -> aa
|
5
20/input_test2
Normal file
5
20/input_test2
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
broadcaster -> aa
|
||||||
|
%aa -> iv, cn
|
||||||
|
&iv -> bb
|
||||||
|
%bb -> cn
|
||||||
|
&cn -> ou
|
296
20/main_part1.s
Normal file
296
20/main_part1.s
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
%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
Normal file
336
20/utils.s
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
[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