finished!
This commit is contained in:
parent
4986e97e2b
commit
ed259baee5
BIN
solve/solve
BIN
solve/solve
Binary file not shown.
295
solve/solve.s
295
solve/solve.s
|
@ -1,10 +1,11 @@
|
||||||
; vim: ft=nasm
|
; vim: ft=nasm
|
||||||
|
s:
|
||||||
|
|
||||||
%macro i_nop 0
|
%macro i_nop 0
|
||||||
db 0x00
|
db 0x00
|
||||||
%endmacro
|
%endmacro
|
||||||
%define np i_nop
|
%define np i_nop
|
||||||
|
|
||||||
|
|
||||||
%macro i_halt 1
|
%macro i_halt 1
|
||||||
db 0x01
|
db 0x01
|
||||||
db %1
|
db %1
|
||||||
|
@ -42,7 +43,8 @@
|
||||||
db 0x50
|
db 0x50
|
||||||
db %1
|
db %1
|
||||||
db %2
|
db %2
|
||||||
db %3
|
db (%3 >> 8) & 0xff
|
||||||
|
db %3 & 0xff
|
||||||
%endmacro
|
%endmacro
|
||||||
%define jl i_less
|
%define jl i_less
|
||||||
|
|
||||||
|
@ -53,10 +55,19 @@
|
||||||
db 0x51
|
db 0x51
|
||||||
db %1
|
db %1
|
||||||
db %2
|
db %2
|
||||||
db %3
|
db (%3 >> 8) & 0xff
|
||||||
|
db %3 & 0xff
|
||||||
%endmacro
|
%endmacro
|
||||||
%define le i_leq
|
%define le i_leq
|
||||||
|
|
||||||
|
%macro break 0
|
||||||
|
sd disp, 0x00
|
||||||
|
sd disp, 0x01
|
||||||
|
sd disp, 0x02
|
||||||
|
sd disp, 0x03
|
||||||
|
np
|
||||||
|
%endmacro
|
||||||
|
|
||||||
%define inp 0
|
%define inp 0
|
||||||
%define disp 1
|
%define disp 1
|
||||||
%define arith 2
|
%define arith 2
|
||||||
|
@ -69,72 +80,324 @@ gt 0x02, inp
|
||||||
gt 0x03, inp
|
gt 0x03, inp
|
||||||
; [a, b, c, d] -> mem
|
; [a, b, c, d] -> mem
|
||||||
sd tape, 0x00
|
sd tape, 0x00
|
||||||
sd tape, 0x01
|
|
||||||
sd tape, 0x02
|
sd tape, 0x02
|
||||||
|
sd tape, 0x01
|
||||||
sd tape, 0x03
|
sd tape, 0x03
|
||||||
; {a, b, c, d}
|
; {a, b, c, d}
|
||||||
|
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
sd arith, 0x03
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x01
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x03, arith
|
||||||
; [i[0], i[1], i[2], i[3] + i[0]]
|
; [i[0], i[1], i[2], i[3] + i[0]]
|
||||||
; - add i[3] and i[0]
|
; - add i[3] and i[0]
|
||||||
|
|
||||||
|
sd arith, 0x01
|
||||||
|
sd arith, 0x03
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x03
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x03, arith
|
||||||
; [i[0], i[1], i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[0], i[1], i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - xor i[1] with i[3] + i[0], pop from arith
|
; - xor i[1] with i[3] + i[0], pop from arith
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
sd arith, 0x01
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x01
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x00, arith
|
||||||
; [i[0] + i[1], i[1], i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[0] + i[1], i[1], i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - add i[0] and i[1], pop from arith
|
; - add i[0] and i[1], pop from arith
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
sd arith, 0x02
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x03
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x02, arith
|
||||||
; [i[0] + i[1], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[0] + i[1], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - xor i[0] + i[1] with i[2], pop from arith
|
; - xor i[0] + i[1] with i[2], pop from arith
|
||||||
|
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
sd arith, 0x02
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x03
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x00, arith
|
||||||
; [i[2], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[2], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - xor (i[0] + i[1]) ^ i[2] with i[0] + i[1], pop from arith
|
; - xor (i[0] + i[1]) ^ i[2] with i[0] + i[1], pop from arith
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
sd arith, 0x01
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x01
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x01, arith
|
||||||
|
sd arith, 0x01
|
||||||
; [i[2], i[2] + i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[2], i[2] + i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - add i[2] + i[1], pop from arith | store i[2] + i[1] in arith
|
; - add i[2] + i[1], pop from arith | store i[2] + i[1] in arith
|
||||||
|
|
||||||
|
gt 0x01, tape
|
||||||
|
sd arith, 0x01
|
||||||
; [i[2], i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[2], i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - pop i[3] from tape use previous i[1] + i[2] from arith to xor
|
; - pop i[3] from tape use previous i[1] + i[2] from arith to xor
|
||||||
|
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x03
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x01, arith
|
||||||
; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - use previous i[1] + i[2] from arith to xor and pop
|
; - use previous i[1] + i[2] from arith to xor and pop
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
; [i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - put i[2] in arith, pop i[1] from tape
|
; - put i[2] in arith, pop i[1] from tape
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x01
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x00, arith
|
||||||
; [i[2] + i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[2] + i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - put i[1] in arith, add, pop
|
; - put i[1] in arith, add, pop
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
sd arith, 0x01
|
||||||
|
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x03
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x00, arith
|
||||||
|
|
||||||
; [i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - xor i[2] + i[1] with (i[2] + i[1]) ^ i[3]
|
; - xor i[2] + i[1] with (i[2] + i[1]) ^ i[3]
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - put i[3] in arith, pop i[2] from tape
|
; - put i[3] in arith, pop i[2] from tape
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x01
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x00, arith
|
||||||
|
|
||||||
; [i[2] + i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[2] + i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - put i[2] in arith, add to i[3]
|
; - put i[2] in arith, add to i[3]
|
||||||
|
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
; [i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - put i[2] + i[3] in arith, pop i[0] from tape
|
; - put i[2] + i[3] in arith, pop i[0] from tape
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x03
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x00, arith
|
||||||
; [(i[2] + i[3]) ^ i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
; [(i[2] + i[3]) ^ i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||||
; - xor in arith
|
; - xor in arith
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
sd tape, 0x01
|
||||||
|
sd tape, 0x02
|
||||||
|
sd tape, 0x03
|
||||||
|
gt 0x01, tape
|
||||||
|
gt 0x02, tape
|
||||||
|
gt 0x03, tape
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
|
||||||
; push all to tape
|
; push all to tape
|
||||||
; pop all back into mem in correct spot
|
; pop all back into mem in correct spot
|
||||||
|
; stage 1 done
|
||||||
|
|
||||||
|
; :b [a, b, c, d] (, ,)
|
||||||
|
sd tape, 0x01
|
||||||
|
; :b [a, b, c, d] (b, , )
|
||||||
|
sd arith, 0x01
|
||||||
|
; :b [a, 0, c, d] (b, 0, +)
|
||||||
|
ld 0x01, 0x00
|
||||||
|
sd arith, 0x01
|
||||||
|
ld 0x01, 0x01
|
||||||
|
sd arith, 0x01
|
||||||
|
; :b [a, t, c, d] (b, 0, +)
|
||||||
|
sd tape, 0x03
|
||||||
|
gt 0x01, tape
|
||||||
|
; :b t [a, t, c, d] (b, 0, +)
|
||||||
|
sd tape, 0x01
|
||||||
|
; :b t [a, b, c, d] ()
|
||||||
|
gt 0x01, arith
|
||||||
|
|
||||||
|
loop:
|
||||||
|
; :b t c [a * c, b, 0, d] ()
|
||||||
|
sd tape, 0x02
|
||||||
|
sd tape, 0x03 ; :b t c d [a, b, c, d]
|
||||||
|
sd tape, 0x00
|
||||||
|
gt 0x03, tape ; :b t c d [a, b, c, a]
|
||||||
|
|
||||||
|
multip:
|
||||||
|
|
||||||
|
sd arith, 0x02
|
||||||
|
ld 0x02, 0x01
|
||||||
|
sd arith, 0x02
|
||||||
|
ld 0x02, 0x02 ; sub 1 from c
|
||||||
|
sd arith, 0x02
|
||||||
|
gt 0x02, arith
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
sd arith, 0x03
|
||||||
|
ld 0x00, 0x01 ; a + a
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, arith
|
||||||
|
sd tape, 0x00 ; :b t c d a+a [a+a, b, c-1, a]
|
||||||
|
|
||||||
|
|
||||||
; routine for doing overflowing add
|
ld 0x00, 0x01 ; :b t c d a+a [1, b, c-1, a]
|
||||||
; [a, b]
|
le 0x02, 0x00, leavemul - s
|
||||||
; [255 - a, b]
|
gt 0x00, tape ; put back a + a
|
||||||
; 255 - a < b
|
|
||||||
; a = b - [255 - a]
|
; :b t c d [a+a, b, c-1, a]
|
||||||
; 255 - a >= b
|
le 0x00, 0x00, multip - s ; jump to mul
|
||||||
; a = a + b
|
|
||||||
;
|
leavemul:
|
||||||
|
|
||||||
|
gt 0x00, tape
|
||||||
|
gt 0x03, tape
|
||||||
|
gt 0x02, tape
|
||||||
|
; :b t [a * c, b, c, d] ()
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
sd arith, 0x01
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x01
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x00, arith
|
||||||
|
; :b t [a * c + b, b, c, d] ()
|
||||||
|
|
||||||
|
modulo:
|
||||||
|
jl 0x00, 0x03, leavemod - s
|
||||||
|
|
||||||
|
sd arith, 0x00
|
||||||
|
sd arith, 0x03
|
||||||
|
|
||||||
|
sd tape, 0x00
|
||||||
|
ld 0x00, 0x02
|
||||||
|
sd arith, 0x00
|
||||||
|
gt 0x00, tape
|
||||||
|
|
||||||
|
gt 0x00, arith
|
||||||
|
|
||||||
|
le 0x00, 0x00, modulo - s
|
||||||
|
|
||||||
|
leavemod:
|
||||||
|
|
||||||
|
; :b t [(ac + b) % d, b, c, d] ()
|
||||||
|
|
||||||
|
gt 0x01, tape
|
||||||
|
; :b [(ac + b) % d, t, c, d] ()
|
||||||
|
sd arith, 0x01
|
||||||
|
ld 0x01, 0x01
|
||||||
|
; :b [(ac + b) % d, 1, c, d] (t, )
|
||||||
|
sd arith, 0x01
|
||||||
|
ld 0x01, 0x02
|
||||||
|
sd arith, 0x01
|
||||||
|
; :b [(ac + b) % d, 1, c, d] (t, 1, -)
|
||||||
|
gt 0x01, arith
|
||||||
|
; :b [(ac + b) % d, t-1, c, d] ()
|
||||||
|
sd tape, 0x02
|
||||||
|
ld 0x02, 0x00
|
||||||
|
le 0x01, 0x02, finish - s
|
||||||
|
|
||||||
|
gt 0x02, tape
|
||||||
|
; if t - 1 leq 0 -> jump out
|
||||||
|
; else -> continue
|
||||||
|
sd arith, 0x02
|
||||||
|
; :b [(ac + b) % d, t-1, c, d] (c, ,)
|
||||||
|
ld 0x02, 0x00
|
||||||
|
sd arith, 0x02
|
||||||
|
ld 0x02, 0x01
|
||||||
|
sd arith, 0x02
|
||||||
|
; :b [(ac + b) % d, t-1, 0, d] (c, 0, +)
|
||||||
|
gt 0x02, tape
|
||||||
|
; : [(ac + b) % d, t-1, b, d] (c, 0, +)
|
||||||
|
sd tape, 0x02
|
||||||
|
; :b [(ac + b) % d, t-1, b, d] (c, 0, +)
|
||||||
|
sd tape, 0x01
|
||||||
|
; :b t-1 [(ac + b) % d, t-1, b, d] (c, 0, +)
|
||||||
|
sd tape, 0x02
|
||||||
|
; :b t-1 b [(ac + b) % d, t-1, b, d] (c, 0, +)
|
||||||
|
gt 0x02, arith
|
||||||
|
; :b t-1 b [(ac + b) % d, t-1, c, d] ()
|
||||||
|
gt 0x01, tape
|
||||||
|
; :b t-1 [(ac + b) % d, b, c, d] ()
|
||||||
|
le 0x03, 0x03, loop - s
|
||||||
|
; if d leq d -> jump loop
|
||||||
|
|
||||||
|
finish:
|
||||||
|
gt 0x02, tape
|
||||||
|
gt 0x01, tape
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
le 0x00, 0x01, label
|
|
||||||
sd disp, 0x00
|
sd disp, 0x00
|
||||||
label:
|
sd disp, 0x01
|
||||||
sd disp, 0x01
|
sd disp, 0x02
|
||||||
|
sd disp, 0x03
|
||||||
|
; finish things
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;le 0x00, 0x01, label
|
||||||
|
;sd disp, 0x00
|
||||||
|
;label:
|
||||||
|
; sd disp, 0x01
|
||||||
|
|
|
@ -6,19 +6,21 @@ pub trait Device {
|
||||||
fn send_byte(&mut self, byte: u8);
|
fn send_byte(&mut self, byte: u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct Reader<'a> {
|
pub struct Reader<'a> {
|
||||||
pub reader: &'a mut dyn Read,
|
pub reader: &'a mut dyn Read,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Device for Reader<'_> {
|
impl Device for Reader<'_> {
|
||||||
fn get_byte(&mut self) -> u8 {
|
fn get_byte(&mut self) -> u8 {
|
||||||
self.reader.bytes().next().and_then(|result| result.ok()).map(|byte| byte as u8).unwrap()
|
self.reader
|
||||||
|
.bytes()
|
||||||
|
.next()
|
||||||
|
.and_then(|result| result.ok())
|
||||||
|
.map(|byte| byte as u8)
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_byte(&mut self, _byte: u8) {
|
fn send_byte(&mut self, _byte: u8) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Tape {
|
pub struct Tape {
|
||||||
|
@ -28,13 +30,12 @@ pub struct Tape {
|
||||||
|
|
||||||
impl Device for Tape {
|
impl Device for Tape {
|
||||||
fn get_byte(&mut self) -> u8 {
|
fn get_byte(&mut self) -> u8 {
|
||||||
let i = self.tape[self.index];
|
|
||||||
if self.index == 0 {
|
if self.index == 0 {
|
||||||
self.index = 25000;
|
self.index = 25000;
|
||||||
}
|
}
|
||||||
self.index -= 1;
|
self.index -= 1;
|
||||||
self.index %= 25000;
|
self.index %= 25000;
|
||||||
i
|
self.tape[self.index]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_byte(&mut self, byte: u8) {
|
fn send_byte(&mut self, byte: u8) {
|
||||||
|
@ -42,7 +43,6 @@ impl Device for Tape {
|
||||||
self.index += 1;
|
self.index += 1;
|
||||||
self.index %= 25000;
|
self.index %= 25000;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Writer<'a> {
|
pub struct Writer<'a> {
|
||||||
|
@ -67,10 +67,10 @@ pub struct Arithmetic {
|
||||||
impl Device for Arithmetic {
|
impl Device for Arithmetic {
|
||||||
fn get_byte(&mut self) -> u8 {
|
fn get_byte(&mut self) -> u8 {
|
||||||
match self.buffer[2] {
|
match self.buffer[2] {
|
||||||
1 => self.buffer[0] + self.buffer[1],
|
1 => self.buffer[0].overflowing_add(self.buffer[1]).0,
|
||||||
2 => self.buffer[0] - self.buffer[1],
|
2 => self.buffer[0].overflowing_sub(self.buffer[1]).0,
|
||||||
3 => self.buffer[0] ^ self.buffer[1],
|
3 => self.buffer[0] ^ self.buffer[1],
|
||||||
_ => 0
|
_ => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,5 +80,3 @@ impl Device for Arithmetic {
|
||||||
self.index %= 3;
|
self.index %= 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
63
src/main.rs
63
src/main.rs
|
@ -3,57 +3,76 @@
|
||||||
mod device;
|
mod device;
|
||||||
mod vm;
|
mod vm;
|
||||||
|
|
||||||
use device::{Reader, Arithmetic, Tape, Writer};
|
use device::{Arithmetic, Reader, Tape, Writer};
|
||||||
use std::io::Cursor;
|
|
||||||
use rand::prelude::random;
|
use rand::prelude::random;
|
||||||
use std::io::Read;
|
use std::fs;
|
||||||
use std::io;
|
use std::io;
|
||||||
use vm::{State, vm_run};
|
use std::io::Cursor;
|
||||||
|
use std::io::Read;
|
||||||
|
use vm::{vm_run, State};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let program: Vec<u8> = io::stdin()
|
||||||
let program: Vec<u8> = io::stdin().bytes().map(|res| res.unwrap_or_else(|_| std::process::exit(1))).collect();
|
.bytes()
|
||||||
|
.map(|res| res.unwrap_or_else(|_| std::process::exit(1)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let iv: [u8; 4] = random();
|
let iv: [u8; 4] = random();
|
||||||
let mut input = Cursor::new(iv);
|
let mut input = Cursor::new(iv);
|
||||||
let mut output = Cursor::new(vec![0,0,0,0]);
|
let mut output = Cursor::new(vec![0, 0, 0, 0]);
|
||||||
|
|
||||||
let state = State {
|
let state = State {
|
||||||
ip: 0usize,
|
ip: 0usize,
|
||||||
mem: [0; 4],
|
mem: [0; 4],
|
||||||
program: program.clone(),
|
program: program.clone(),
|
||||||
devices: vec![Box::new(Reader { reader: &mut input } ),
|
devices: vec![
|
||||||
Box::new(Writer { writer: &mut output } ),
|
Box::new(Reader { reader: &mut input }),
|
||||||
Box::new(Arithmetic { buffer: [0; 3], index: 0usize }),
|
Box::new(Writer {
|
||||||
Box::new(Tape { tape: [0; 25000], index: 0usize }),]
|
writer: &mut output,
|
||||||
|
}),
|
||||||
|
Box::new(Arithmetic {
|
||||||
|
buffer: [0; 3],
|
||||||
|
index: 0usize,
|
||||||
|
}),
|
||||||
|
Box::new(Tape {
|
||||||
|
tape: [0; 25000],
|
||||||
|
index: 0usize,
|
||||||
|
}),
|
||||||
|
],
|
||||||
};
|
};
|
||||||
vm_run(state);
|
vm_run(state);
|
||||||
let ov: [u8; 4] = output.into_inner().try_into().unwrap();
|
let ov: [u8; 4] = output.into_inner().try_into().unwrap();
|
||||||
println!("{:?}", iv);
|
|
||||||
println!("{:?}", encrypt(iv));
|
|
||||||
println!("{:?}", ov);
|
|
||||||
if ov != encrypt(iv) {
|
if ov != encrypt(iv) {
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
fs::read_to_string("flag.txt").unwrap_or_else(|_| {
|
||||||
|
println!("Couldn't open flag file, please contact an admin if on the server.");
|
||||||
|
std::process::exit(1)
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
fn encrypt(block: [u8; 4]) -> [u8; 4] {
|
fn encrypt(block: [u8; 4]) -> [u8; 4] {
|
||||||
let mut block = block;
|
let mut block = block;
|
||||||
|
|
||||||
|
#[allow(clippy::clone_on_copy)]
|
||||||
|
let mut b = block.clone();
|
||||||
|
|
||||||
let (i, _) = block[0].overflowing_add(block[3]);
|
let (i, _) = block[0].overflowing_add(block[3]);
|
||||||
block[1] ^= i;
|
b[1] ^= i;
|
||||||
let (i, _) = block[1].overflowing_add(block[0]);
|
let (i, _) = block[1].overflowing_add(block[0]);
|
||||||
block[2] ^= i;
|
b[2] ^= i;
|
||||||
let (i, _) = block[2].overflowing_add(block[1]);
|
let (i, _) = block[2].overflowing_add(block[1]);
|
||||||
block[3] ^= i;
|
b[3] ^= i;
|
||||||
let (i, _) = block[3].overflowing_add(block[2]);
|
let (i, _) = block[3].overflowing_add(block[2]);
|
||||||
block[0] ^= i;
|
b[0] ^= i;
|
||||||
|
|
||||||
|
block = b;
|
||||||
|
|
||||||
for _ in 0..block[3] {
|
for _ in 0..block[3] {
|
||||||
let (mul, _) = block[2].overflowing_mul(block[0]);
|
let (mul, _) = block[2].overflowing_mul(block[0]);
|
||||||
|
|
23
src/vm.rs
23
src/vm.rs
|
@ -5,7 +5,7 @@ pub struct State<'a> {
|
||||||
pub ip: usize,
|
pub ip: usize,
|
||||||
pub mem: [u8; 4],
|
pub mem: [u8; 4],
|
||||||
pub program: Vec<u8>,
|
pub program: Vec<u8>,
|
||||||
pub devices: Vec<Box<dyn Device + 'a>>
|
pub devices: Vec<Box<dyn Device + 'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State<'_> {
|
impl State<'_> {
|
||||||
|
@ -25,10 +25,10 @@ impl State<'_> {
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn next_dword(&mut self) -> u32 {
|
fn next_dword(&mut self) -> u32 {
|
||||||
let result = (u32::from(self.program[self.ip]) << 24) |
|
let result = (u32::from(self.program[self.ip]) << 24)
|
||||||
(u32::from(self.program[self.ip + 1]) << 16) |
|
| (u32::from(self.program[self.ip + 1]) << 16)
|
||||||
(u32::from(self.program[self.ip + 2]) << 8) |
|
| (u32::from(self.program[self.ip + 2]) << 8)
|
||||||
(u32::from(self.program[self.ip + 3]));
|
| (u32::from(self.program[self.ip + 3]));
|
||||||
self.ip += 4;
|
self.ip += 4;
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
@ -43,10 +43,8 @@ pub enum Opcode {
|
||||||
Get,
|
Get,
|
||||||
Less,
|
Less,
|
||||||
LessEq,
|
LessEq,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl From<u8> for Opcode {
|
impl From<u8> for Opcode {
|
||||||
fn from(v: u8) -> Self {
|
fn from(v: u8) -> Self {
|
||||||
match v {
|
match v {
|
||||||
|
@ -57,18 +55,16 @@ impl From<u8> for Opcode {
|
||||||
0x21 => Opcode::Get,
|
0x21 => Opcode::Get,
|
||||||
0x50 => Opcode::Less,
|
0x50 => Opcode::Less,
|
||||||
0x51 => Opcode::LessEq,
|
0x51 => Opcode::LessEq,
|
||||||
_ => Opcode::Halt
|
_ => Opcode::Halt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn vm_run(mut state: State) -> i32 {
|
pub fn vm_run(mut state: State) -> i32 {
|
||||||
loop {
|
loop {
|
||||||
if state.ip >= state.program.len() {
|
if state.ip >= state.program.len() {
|
||||||
return 1
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
match Opcode::from(state.program[state.ip]) {
|
match Opcode::from(state.program[state.ip]) {
|
||||||
Opcode::Nop => {
|
Opcode::Nop => {
|
||||||
state.ip += 1;
|
state.ip += 1;
|
||||||
|
@ -100,7 +96,7 @@ pub fn vm_run(mut state: State) -> i32 {
|
||||||
state.ip += 1;
|
state.ip += 1;
|
||||||
let mem1 = state.mem[state.next_byte() as usize];
|
let mem1 = state.mem[state.next_byte() as usize];
|
||||||
let mem2 = state.mem[state.next_byte() as usize];
|
let mem2 = state.mem[state.next_byte() as usize];
|
||||||
let jump = state.next_byte() as usize;
|
let jump = state.next_word() as usize;
|
||||||
if mem1 < mem2 {
|
if mem1 < mem2 {
|
||||||
state.ip = jump;
|
state.ip = jump;
|
||||||
}
|
}
|
||||||
|
@ -109,12 +105,11 @@ pub fn vm_run(mut state: State) -> i32 {
|
||||||
state.ip += 1;
|
state.ip += 1;
|
||||||
let mem1 = state.mem[state.next_byte() as usize];
|
let mem1 = state.mem[state.next_byte() as usize];
|
||||||
let mem2 = state.mem[state.next_byte() as usize];
|
let mem2 = state.mem[state.next_byte() as usize];
|
||||||
let jump = state.next_byte() as usize;
|
let jump = state.next_word() as usize;
|
||||||
if mem1 <= mem2 {
|
if mem1 <= mem2 {
|
||||||
state.ip = jump;
|
state.ip = jump;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user