asm.py (5680B)
1import random 2 3random.seed(133713371337) 4 5asm = """ 6 not r0 7 mov r0, r2 8 ldb r0, r3 # lsfr 9 jnz chk_loop 10 11lsfr_advance: 12 # bit 0 13 mov r3, r0 14 shr r3, 1 15 shl r0, 7 16 xor r0, r3 17 18 # bit 3 19 mov r3, r0 20 shr r0, 2 21 shl r0, 7 22 xor r0, r3 23 24 # bit 6 25 mov r3, r0 26 shr r0, 5 27 shl r0, 7 28 xor r0, r3 29 30 # if != 0, jmp, else 31 # fallthrough to same location 32 jnz lsfr_advance_ret 33 34chk_loop: 35 jnz lsfr_advance 36lsfr_advance_ret: 37 38 xor r0, r0 39 not r0 40 shr r0, 3 41 and r3, r0 42 43 xor r1, r1 44 inc r1 45 shl r1, 7 46 add r1, r0 47 ldb r0, r1 48 49 jnz check_val 50check_val_ret: 51 52 mov r1, r0 53 jnz chk_loop 54 55 not r0 56 jnz end1 57 58check_val: 59 inp r0 60 xor r3, r1 61 xor r0, r1 62 not r1 63 and r1, r2 64 mov r0, r1 65 66 xor r0, r0 67 not r0 68 jnz check_val2 69check_val2_ret: 70 jnz check_val_ret 71 72end1: 73 jnz end2 74 75check_val2: 76 xor r0, r0 77 inc r0 78 shl r0, 2 79 inc r0 80 shl r0, 1 81 xor r0, r1 82 83 jnz check_val2_ret 84 85end2: 86 mov r2, r0 87 not r0 88 jnz print_fail 89 not r0 90 jnz print_ok 91 92print_fail: 93 xor r2, r2 94 not r2 95 shl r2, 3 96 jnz print 97 98print_ok: 99 xor r2, r2 100 not r2 101 shl r2, 4 102 103print: 104 xor r1, r1 105 inc r1 106print_loop: 107 ldb r2, r0 108 jnz print_cont 109 hlt 110print_cont: 111 out r0 112 add r1, r2 113 jnz print_loop 114 115""" 116 117flag = b"ALLES!{T3553L4T3!}\x0a" 118 119data = {} 120 121# ensure lsfr hits different indexes 122seed_ok = False 123lsfr_init = None 124for lsfr_init in range(0x6f, 256): 125 reg = lsfr_init 126 data.clear() 127 seed_ok = True 128 vals = [] 129 for i,c in enumerate(flag): 130 b = (reg >> 6) & 0x01 131 b ^= (reg >> 3) & 0x01 132 b ^= (reg >> 0) & 0x01 133 reg = (b << 7) | (reg >> 1) 134 vals.append(reg) 135 addr = 0x80 + (reg & 0x1f) 136 vals.append(addr) 137 if addr in data: 138 seed_ok = False 139 data[addr] = c ^ reg 140 if seed_ok: 141 print("vals", [hex(v) for v in vals]) 142 break 143assert(seed_ok) 144 145for i,b in enumerate(b"ok\n\x00"): 146 data[0xf0+i] = b 147 148for i,b in enumerate(b"fail\n\x00"): 149 data[0xf8+i] = b 150 151data[0xff] = lsfr_init 152 153bytecode = [] 154labels = {} 155for l in asm.split("\n"): 156 l = l.replace(",", " ").strip().lower() 157 if ":" in l: 158 name = l.split(":")[0] 159 labels[name] = len(bytecode) 160 continue 161 elif l == "" or l.strip().startswith("#"): 162 continue 163 cmd, ops = l.split()[0], l.split()[1:3] 164 if cmd == "jnz": 165 name, = ops 166 bytecode.append(name) 167 elif cmd == "shl": 168 r1,sh = int(ops[0][1:]), int(ops[1]) 169 assert(r1 >= 0 and r1 < 4) 170 assert(sh >= 0 and sh < 8) 171 bytecode.append(0b01000000 | (r1 << 3) | sh) 172 elif cmd == "shr": 173 r1,sh = int(ops[0][1:]), int(ops[1]) 174 assert(r1 >= 0 and r1 < 4) 175 assert(sh >= 0 and sh < 8) 176 bytecode.append(0b01100000 | (r1 << 3) | sh) 177 elif cmd == "mov": 178 r1,r2 = [int(o[1:]) for o in ops] 179 assert(r1 >= 0 and r1 < 4) 180 assert(r2 >= 0 and r2 < 4) 181 bytecode.append(0b00100000 | (r1 << 2) | r2) 182 elif cmd == "swp": 183 r1,r2 = [int(o[1:]) for o in ops] 184 assert(r1 >= 0 and r1 < 4) 185 assert(r2 >= 0 and r2 < 4) 186 bytecode.append(0b00110000 | (r1 << 2) | r2) 187 elif cmd == "add": 188 r1,r2 = [int(o[1:]) for o in ops] 189 assert(r1 >= 0 and r1 < 4) 190 assert(r2 >= 0 and r2 < 4) 191 bytecode.append(0b10000000 | (r1 << 2) | r2) 192 elif cmd == "sub": 193 r1,r2 = [int(o[1:]) for o in ops] 194 assert(r1 >= 0 and r1 < 4) 195 assert(r2 >= 0 and r2 < 4) 196 bytecode.append(0b10010000 | (r1 << 2) | r2) 197 elif cmd == "xor": 198 r1,r2 = [int(o[1:]) for o in ops] 199 assert(r1 >= 0 and r1 < 4) 200 assert(r2 >= 0 and r2 < 4) 201 bytecode.append(0b10100000 | (r1 << 2) | r2) 202 elif cmd == "and": 203 r1,r2 = [int(o[1:]) for o in ops] 204 assert(r1 >= 0 and r1 < 4) 205 assert(r2 >= 0 and r2 < 4) 206 bytecode.append(0b10110000 | (r1 << 2) | r2) 207 elif cmd == "ldb": 208 r1,r2 = [int(o[1:]) for o in ops] 209 assert(r1 >= 0 and r1 < 4) 210 assert(r2 >= 0 and r2 < 4) 211 bytecode.append(0b11000000 | (r1 << 2) | r2) 212 elif cmd == "stb": 213 r1,r2 = [int(o[1:]) for o in ops] 214 assert(r1 >= 0 and r1 < 4) 215 assert(r2 >= 0 and r2 < 4) 216 bytecode.append(0b11010000 | (r1 << 2) | r2) 217 elif cmd == "inp": 218 reg, = [int(o[1:]) for o in ops] 219 assert(reg >= 0 and reg < 4) 220 bytecode.append(0b11100000 | reg) 221 elif cmd == "out": 222 reg, = [int(o[1:]) for o in ops] 223 assert(reg >= 0 and reg < 4) 224 bytecode.append(0b11100100 | reg) 225 elif cmd == "not": 226 reg, = [int(o[1:]) for o in ops] 227 assert(reg >= 0 and reg < 4) 228 bytecode.append(0b11101000 | reg) 229 elif cmd == "inc": 230 reg, = [int(o[1:]) for o in ops] 231 assert(reg >= 0 and reg < 4) 232 bytecode.append(0b11110000 | reg) 233 #elif cmd == "dec": 234 # reg, = [int(o[1:]) for o in ops] 235 # assert(reg >= 0 and reg < 4) 236 # bytecode.append(0b11110100 | reg) 237 elif cmd == "hlt": 238 bytecode.append(0b11111111) 239 else: 240 print(cmd) 241 assert(False) 242 243for i,b in enumerate(bytecode): 244 if type(b) == str: 245 off = labels[b] - (i + 1) + 16 246 print(b, off) 247 assert(off >= 0 and off < 32) 248 bytecode[i] = 0b00000000 | off 249 250print(len(bytecode), bytecode) 251bytecode += random.randbytes(0x100 - len(bytecode)) 252for p,v in data.items(): 253 bytecode[p] = v 254 255for i in range(4): 256 with open(f"build/memory{i+1}.bin", "wb+") as f: 257 f.write(bytes(bytecode[i*64:i*64+64])) 258