def code(zlang, d=None): if d is None: d = {} zlang = replaced_zlang(zlang, d) asm = asm_code(zlang) c = machine_code(asm) return c
def test_return(): asm = """ set a1 2 .return 16 halt """ return_asm = """ set a1 2 set2 a3 18 subtract2 f1 a3 f1 load_from_register2 f1 a2 jump_from_register a2 halt """ expected = x16asm.machine_code(return_asm) output = x16asm.machine_code(asm) assert expected == output
def test_set(): asm = """ set a1 1 halt """ input = asm b = [0, 16, 1, 255] expected = b + [0] * (65536 - len(b)) result = x16asm.machine_code(input) assert expected == result, result
def test_function_multiply(): asm = """ jump @1024 .memory 1024 set2 f1 3 jump @function_end @function_multiply ; 1031 set2 a3 2 save_from_register2 a1 f1 ; a1 入栈 add2 a3 f1 f1 save_from_register2 a2 f1 ; a2 入栈 add2 a3 f1 f1 set2 a3 2 @while_start ; set2 a2 2 subtract2 f1 a2 a2 load_from_register2 a2 a2 compare a2 a3 ; jump_if_less @while_end ; 一旦 a2 小于 a3,就结束循环 set2 a2 1 add2 a3 a2 a3 ; a3 + 1 set2 a2 4 subtract2 f1 a2 a2 load_from_register2 a2 a2 add2 a1 a2 a1 ; 累加结果 jump @while_start @while_end ;72 .return 4 @function_end set2 a1 5 set2 a2 100 .call @function_multiply halt """ code = machine_code(asm) memory = code + [0] * (2 ** 16 - len(code)) cpu = Opu(memory) cpu.run() output = [ cpu.registers["a1"], ] print("output", output) expected = [ 500, ] ensure(expected == output, 'test_function_multiply') assert expected == output
def test_shift_right(): input = """ set a1 20 shift_right a1 """ b = [ 0, 16, 20, 17, 16 ] expected = b + [0] * (65536 - len(b)) result = x16asm.machine_code(input) assert expected == result, result
def test_dot_data(): input = """ set a1 2 .data 12 23 43 2 halt """ code = [ 0, 16, 2, 12, 23, 43, 2, 255 ] expected = code + [0] * (65536 - len(code)) result = x16asm.machine_code(input) assert expected == result, result
def test3(): asm = """ set a1 1 set a2 2 add a1 a2 a1 halt """ AxePU = x16vm.AxePU # case = cases[2] memory = x16asm.machine_code(asm) # memory = code cpu = AxePU(memory) x16vm._run(cpu) output = cpu.data['a1'] expected = 3 assert expected == output, output
def test_and(): asm = """ set a1 15 set a2 1 and a1 a2 a3 halt """ AxePU = x16vm.AxePU # case = cases[2] memory = x16asm.machine_code(asm) # memory = code cpu = AxePU(memory) x16vm._run(cpu) # output = memory[100] output = cpu.data['a3'] expected = 1 assert expected == output, output
def test_shift_right(): asm = """ set a1 20 shift_right a1 halt """ AxePU = x16vm.AxePU # case = cases[2] memory = x16asm.machine_code(asm) # memory = code cpu = AxePU(memory) x16vm._run(cpu) # output = memory[100] output = cpu.data['a1'] expected = 10 assert expected == output, output
def test_add2(): asm = """ set2 a1 2000 set2 a2 1000 add2 a1 a2 a1 halt """ AxePU = x16vm.AxePU # case = cases[2] memory = x16asm.machine_code(asm) # memory = code cpu = AxePU(memory) x16vm._run(cpu) # output = memory[100] output = cpu.data['a1'] expected = 3000 assert expected == output, output
def test_save_from_register(): asm = """ set a1 4 set a2 100 save_from_register a1 a2 halt """ AxePU = x16vm.AxePU # case = cases[2] memory = x16asm.machine_code(asm) # memory = code cpu = AxePU(memory) x16vm._run(cpu) output = memory[100] # output = memory[100] expected = 4 assert expected == output, output
def test4(): asm = """ set a1 1 set a2 2 add a1 a2 a1 save a1 @100 halt """ AxePU = x16vm.AxePU # case = cases[2] memory = x16asm.machine_code(asm) # memory = code cpu = AxePU(memory) x16vm._run(cpu) output = memory[100] expected = 3 assert expected == output, output
def test_load_from_register2(): asm = """ set2 a1 65535 set2 a2 100 save_from_register2 a1 a2 load_from_register2 a2 a3 halt """ AxePU = x16vm.AxePU # case = cases[2] memory = x16asm.machine_code(asm) # memory = code cpu = AxePU(memory) x16vm._run(cpu) # output = memory[100] output = cpu.data['a3'] expected = 65535 assert expected == output, output
def test_save_from_register2(): asm = """ set2 a1 65535 set2 a2 100 save_from_register2 a1 a2 halt """ AxePU = x16vm.AxePU # case = cases[2] memory = x16asm.machine_code(asm) # memory = code cpu = AxePU(memory) x16vm._run(cpu) output = memory[100] print(output) print(memory[101]) assert memory[100] == 255 assert memory[101] == 255
def test_and(): input = """ set a1 15 # bbb set a2 1 and a1 a2 a3 # aaa """ b = [ 0, 16, 15, 0, 32, 1, 19, 16, 32, 48 ] expected = b + [0] * (65536 - len(b)) result = x16asm.machine_code(input) assert expected == result, result
def test_shift_right(): asm = """ set a1 20 shift_right a1 halt """ code = machine_code(asm) memory = code + [0] * (2 ** 16 - len(code)) cpu = Opu(memory) cpu.run() expected = [ 10, ] output = [ cpu.registers["a1"], ] print("register", cpu.registers) assert expected == output
def test_compare(): asm = """ set a1 1 set a2 2 add a1 a2 a1 save a1 @100 compare a1 a2 halt """ AxePU = x16vm.AxePU # case = cases[2] memory = x16asm.machine_code(asm) # memory = code cpu = AxePU(memory) x16vm._run(cpu) output = cpu.data['c1'] # output = memory[100] expected = 2 assert expected == output, output
def test_draw_column(): with open('hello.a16') as f: func_asm = f.read() asm = """ set2 a3 6 add2 f1 a3 f1 set2 a1 16 set2 a3 6 ; 保存「变量 1」column subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 4 set2 a3 4 ; 保存「变量 2」x subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 0 set2 a3 2 ; 保存「变量 3」y subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; .call @function_draw_column set2 a3 6 subtract2 f1 a3 a3 halt .memory 64512 .data 92 214 116 0 238 16 238 0 132 254 128 0 254 146 242 0 """ asm = func_asm + asm AxePU = x16vm.AxePU memory = x16asm.machine_code(asm) cpu = AxePU(memory) x16vm._run(cpu) output1 = memory[65089] output2 = memory[65153] expected = 195 canvas = x16vm.Canvas(20) canvas.draw(memory[65024:])
def test_draw_point(): with open('hello.a16') as f: func_asm = f.read() asm = """ set2 a3 4 add2 f1 a3 f1 set2 a1 3 set2 a3 4 ; 保存「变量 1」x subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set a1 2 set2 a3 2 ; 保存「变量 2」y subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; .call @function_draw_point set2 a3 4 subtract2 f1 a3 a3 halt .memory 64512 .data 92 214 116 0 238 16 238 0 132 254 128 0 254 146 242 0 """ asm = func_asm + asm AxePU = x16vm.AxePU memory = x16asm.machine_code(asm) cpu = AxePU(memory) x16vm._run(cpu) output = memory[65091] expected = 195 canvas = x16vm.Canvas(20) canvas.draw(memory[65024:]) assert expected == output, output
def test_and(): asm = """ set a1 31 set a2 12 and a1 a2 a3 halt """ code = machine_code(asm) memory = code + [0] * (2 ** 16 - len(code)) cpu = Opu(memory) cpu.run() expected = [ 31, 12, 12, ] output = [ cpu.registers["a1"], cpu.registers["a2"], cpu.registers["a3"], ] print("register", cpu.registers) assert expected == output
def test_call(): asm = """ jump @1024 .memory 1024 set2 f1 3 jump @function_end ; a1, a2 用来存参数 @function_multiply ;1031 set2 a3 2 ; 65534(a1), 65532(a2), 65530(a3), save2 a1 @65534 @while_start ;1039 compare a2 a3 jump_if_less @while_end ; a3 += 1 save2 a2 @65532 set2 a2 1 add2 a3 a2 a3 ; a1 += a1 load2 @65534 a2 add2 a1 a2 a1 ; load2 @65532 a2 jump @while_start @while_end ; f1 -= 2 set2 a3 2 subtract2 f1 a3 f1 load_from_register2 f1 a2 jump_from_register a2 @function_end ;1085 ; 调用函数 set2 a1 300 set2 a2 10 ; 保存函数执行结束后去往的地址 ; set2 a3 14 ;1097 ; add2 pa a3 a3 ; save_from_register2 a3 f1 ; 3byte ; set2 a3 2 ; 4byte ; add2 f1 a3 f1 ; 4byte ; jump @function_multiply ; 3byte .call @function_multiply halt ;1115 """ expected = [ 6, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 3, 0, 6, 61, 4, 8, 48, 2, 0, 11, 16, 254, 255, 4, 32, 48, 5, 48, 4, 11, 32, 252, 255, 8, 32, 1, 0, 10, 48, 32, 48, 9, 254, 255, 32, 10, 16, 32, 16, 9, 252, 255, 32, 6, 15, 4, 8, 48, 2, 0, 12, 80, 48, 80, 14, 80, 32, 16, 32, 8, 16, 44, 1, 8, 32, 10, 0, 8, 48, 14, 0, 10, 0, 48, 48, 15, 48, 80, 8, 48, 2, 0, 10, 80, 48, 80, 6, 7, 4, 255, ] result = x16asm.machine_code(asm) expected = expected + [0] * (65536 - len(expected)) assert expected == result, result
def test_call_and_return(): asm = """ jump @1024 .memory 1024 set2 f1 3 ; 我们要在接下来的的内存存放函数定义,所以直接跳转到 @function_end 避免执行函数 jump @function_end ; a1, a2 用来存参数 @function_multiply ; 局部变量空间 ; set2 a3 8 ; f1 += 8 对应 .return 8 add2 f1 a3 f1 ; set2 a3 2 ; 保存「变量 1」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a3 4 ; 保存「变量 2」 subtract2 f1 a3 a3 ; save_from_register2 a2 a3 ; set2 a1 1 ; 用于 while 判断 set2 a3 6 ; 保存「变量 3」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 0 ; 作为累加的 result set2 a3 8 ; 保存「变量 4」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; @while_start ; 判断循环条件 ; set2 a3 4 ; 读取「变量 2」 subtract2 f1 a3 a3 ; load_from_register2 a3 a1 ; set2 a3 6 ; 读取「变量 3」 subtract2 f1 a3 a3 ; load_from_register2 a3 a2 ; compare a1 a2 jump_if_less @while_end ;「变量 3」 += 1 ; set2 a3 6 ; 读取「变量 3」 subtract2 f1 a3 a3 ; load_from_register2 a3 a1 ; set2 a3 1 add a1 a3 a1 set2 a3 6 ; 保存「变量 3」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; ;「变量 4」 += 「变量 1」 ; set2 a3 8 ; 读取「变量 4」 subtract2 f1 a3 a3 ; load_from_register2 a3 a1 ; set2 a3 2 ; 读取「变量 1」 subtract2 f1 a3 a3 ; load_from_register2 a3 a2 ; add2 a1 a2 a1 set2 a3 8 ; 保存「变量 4」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; jump @while_start @while_end ; 「变量 4」作为函数返回值,放入 a1 ; set2 a3 8 ; 读取「变量 4」 subtract2 f1 a3 a3 ; load_from_register2 a3 a1 ; .return 8 ; 所有函数定义结束的标记(但我们这个例子中,只有一个函数定义) @function_end ; 调用函数 set2 a1 300 set2 a2 10 .call @function_multiply save2 a1 @65530 ; 用于校验测试结果 halt """ AxePU = x16vm.AxePU # case = cases[2] memory = x16asm.machine_code(asm) # memory = code cpu = AxePU(memory) x16vm._run(cpu) # output = memory[100] output = cpu.data['a1'] expected = 3000 assert expected == output, output
""" input = asm b = [0, 16, 1, 255] expected = b + [0] * (65536 - len(b)) result = x16asm.machine_code(input) assert expected == result, result def test_load(): case = cases[1] a, b = case input = a expected = b + [0] * (65536 - len(b)) result = x16asm.machine_code(input) assert expected == result, result def test_add(): case = cases[2] a, b = case input = a expected = b + [0] * (65536 - len(b)) result = x16asm.machine_code(input) assert expected == result, result def test_save(): case = cases[3]
def test_factorial_a16(): func_asm = """ jump @1024 .memory 1024 set2 f1 3 jump @function_end ; a1, a2 用来存参数 @multiply ; 局部变量空间 ; set2 a3 8 ; f1 += 8 对应 .return 8 add2 f1 a3 f1 ; set2 a3 2 ; 保存「变量 1」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a3 4 ; 保存「变量 2」 subtract2 f1 a3 a3 ; save_from_register2 a2 a3 ; set2 a1 1 ; 用于 while 判断 set2 a3 6 ; 保存「变量 3」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 0 ; 作为累加的 result set2 a3 8 ; 保存「变量 4」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; @while_start ; 判断循环条件 ; set2 a3 4 ; 读取「变量 2」 subtract2 f1 a3 a3 ; load_from_register2 a3 a1 ; set2 a3 6 ; 读取「变量 3」 subtract2 f1 a3 a3 ; load_from_register2 a3 a2 ; compare a1 a2 jump_if_less @while_end ;「变量 3」 += 1 ; set2 a3 6 ; 读取「变量 3」 subtract2 f1 a3 a3 ; load_from_register2 a3 a1 ; set2 a3 1 add2 a1 a3 a1 set2 a3 6 ; 保存「变量 3」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; ;「变量 4」 += 「变量 1」 ; set2 a3 8 ; 读取「变量 4」 subtract2 f1 a3 a3 ; load_from_register2 a3 a1 ; set2 a3 2 ; 读取「变量 1」 subtract2 f1 a3 a3 ; load_from_register2 a3 a2 ; add2 a1 a2 a1 set2 a3 8 ; 保存「变量 4」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; jump @while_start @while_end ; 「变量 4」作为函数返回值,放入 a1 ; set2 a3 8 ; 读取「变量 4」 subtract2 f1 a3 a3 ; load_from_register2 a3 a1 ; .return 8 @factorial set2 a3 4 add2 f1 a3 f1 ;申请了4个内存 set2 a3 2 ; 保存「变量 1」 subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a2 2 set2 a3 4 ; 保存「变量 2」 subtract2 f1 a3 a3 ; save_from_register2 a2 a3 ; set2 a3 2 ; 读取「变量 1」 subtract2 f1 a3 a3 ; load_from_register2 a3 a1 ; set2 a3 4 ; 读取「变量 2」 subtract2 f1 a3 a3 ; load_from_register2 a3 a2 ; compare a1 a2 jump_if_less @label1 set2 a3 1 ; a1 = a1 -1 subtract2 a1 a3 a1 ; .call @factorial set2 a3 0 add2 a3 a1 a2 set2 a3 2 ; 读取「变量 1」 subtract2 f1 a3 a3 ; load_from_register2 a3 a1 ; .call @multiply @label1 .return 4 @function_end ;set a1 3 ;.call @factorial ;halt """ AxePU = x16vm.AxePU call_asm = """ ; 调用函数 set2 a1 5 .call @factorial ; 校验测试结果 save2 a1 @65530 halt """ asm = func_asm + call_asm memory = x16asm.machine_code(asm) cpu = AxePU(memory) x16vm._run(cpu) assert memory[65530] == 24 * 5
def test06(): asm = """ jump @33795 .memory 33795 set2 f1 32772 ;栈内存 set2 a3 3 ; 显存地址 save_from_register2 a3 f1; 显存地址入栈 set2 a3 2 add2 f1 a3 f1 ;f1+2 set2 a1 5 ; x=5 save_from_register2 a1 f1; x入栈 set2 a3 2 add2 f1 a3 f1 ;f1+2 set2 a1 5 ; y=5 save_from_register2 a1 f1; y入栈 set2 a3 2 add2 f1 a3 f1 ;f1+2 .call @function_draw_point halt ; a1, a2 承受局部变量 ; a1 保存最后的结果 ; a3 工具 @function_draw_point set2 a3 32772 load_from_register2 a3 a1 ;显存地址出栈 set2 a3 6 subtract2 f1 a3 a3 ;x出栈 load_from_register2 a3 a2 ;a2 = 5 save_from_register2 a2 a1 ; 把x保存到当前的显存地址([3]=5) set2 a3 2 add2 a3 a1 a2 ; 显存地址+2(3+2=5) set2 a3 32772 save_from_register2 a2 a3 ;显存地址存到栈内存里面 set2 a3 32772 load_from_register2 a3 a1 ;显存地址出栈 set2 a3 4 subtract2 f1 a3 a3 ;y出栈 load_from_register2 a3 a2 save_from_register2 a2 a1 ; 把y保存到当前的显存地址(5) set2 a3 2 add2 a3 a2 a2 ; 显存地址+2(5+2) ;我要如何把加完以后的显存地址存到f1里面去呢 set2 a3 32772 save_from_register2 a2 a3 ;显存地址存到栈内存里面 set2 a3 32772 load_from_register2 a3 a2 ;显存地址出栈 set2 a1 255 save_from_register a1 a2 set2 a3 2 add2 a3 a2 a2 ; 显存地址+2(7+2) set2 a3 32772 save_from_register2 a2 a3 ;显存地址存到栈内存里面 .return 0 """ memory = machine_code(asm) memory = memory + [0] * (2 ** 16 - len(memory)) cpu = Opu(memory) cpu.run() output = cpu.memory[3:9] expected = [5, 0, 5, 0, 255, 0] print("32772", cpu.memory[32772]) assert output == expected, output
def test05(): """ 以下汇编函数相当于在做这个事情 a = 1 b = 2 c = 6 d = 9 e = d - c - b -a """ asm = """ jump @33795 .memory 33795 set2 f1 32772 ;栈内存 set2 a3 2; add2 f1 a3 f1;为显存留一个地方 set2 a1 1 ; a=1 save_from_register2 a1 f1; a入栈 set2 a3 2 add2 f1 a3 f1 ;f1+2 set2 a1 2 ; b=2 save_from_register2 a1 f1; b入栈 set2 a3 2 add2 f1 a3 f1 ;f1+2 set2 a1 6 ; c=6 save_from_register2 a1 f1; c入栈 set2 a3 2 add2 f1 a3 f1 ;f1+2 set2 a1 9 ; d=9 save_from_register2 a1 f1; d入栈 set2 a3 2 add2 f1 a3 f1 ;f1+2 .call @bin_add halt ; a1, a2 承受局部变量 ; a1 保存最后的结果 ; a3 工具 @bin_add set2 a3 4 subtract2 f1 a3 a3 ;d出栈 load_from_register2 a3 a1 set2 a3 10 subtract2 f1 a3 a3 ;a出栈 load_from_register2 a3 a2 subtract2 a1 a2 a1 ; e = d - a set2 a3 8 subtract2 f1 a3 a3 ;b出栈 load_from_register2 a3 a2 subtract2 a1 a2 a1 ; e = d - a - b set2 a3 6 subtract2 f1 a3 a3 ;c出栈 load_from_register2 a3 a2 subtract2 a1 a2 a1 ; e = d - a - b - c halt .return 0 """ memory = machine_code(asm) memory = memory + [0] * (2 ** 16 - len(memory)) cpu = Opu(memory) cpu.run() output = cpu.registers['a1'] expected = 0 print('output', output) assert output == expected, output
def test_factorial(): asm = """ jump @1024 .memory 1024 set2 f1 3 jump @function_end ; ; @function_multiply set2 a3 2 ; 因为下面用 a2 < a3 做判断,所以 a3 从 2 开始 save2 a1 @65534 @while_start ; 循环开始 compare a2 a3 ; jump_if_less @while_end ; 一旦 a2 小于 a3,就结束循环 save2 a2 @65532 set2 a2 1 add2 a3 a2 a3 load2 @65534 a2 add2 a1 a2 a1 load2 @65532 a2 jump @while_start @while_end set2 a3 2 subtract2 f1 a3 f1 load_from_register2 f1 a2 jump_from_register a2 ; ; @factorial ; 存 a1 f1 += 2 save_from_register2 a1 f1 set2 a3 2 add2 f1 a3 f1 ; if n < 2 set2 a2 2 compare a1 a2 jump_if_less @factorial_return ; n - 1 set2 a2 1 subtract2 a1 a2 a1 ; 递归 .call @factorial ; 取出上次暂存的 a1 放入 a2 set2 a3 2 subtract2 f1 a3 f1 load_from_register2 f1 a2 .call @function_multiply .return 0 ; 返回 1 @factorial_return set2 a1 1 .return 2 ; ; @function_end set2 a1 4 .call @factorial halt """ code = machine_code(asm) memory = code + [0] * (2 ** 16 - len(code)) cpu = Opu(memory) cpu.run() output = [ cpu.registers["a1"], ] expected = [ 24, ] ensure(expected == output, 'test_factorial') assert output == expected, output
def code(path): p = path zlang = read_zlang(p) asm = asm_code(zlang) c = machine_code(asm) return c
def test_draw_char(): with open('hello.a16') as f: func_asm = f.read() asm = """ ; 0 set2 a3 6 add2 f1 a3 f1 set2 a1 0 set2 a3 6 ; 保存「变量 code subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 0 set2 a3 4 ; 保存「变量 2」x subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 0 set2 a3 2 ; 保存「变量 3」y subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; .call @function_draw_char set2 a3 6 subtract2 f1 a3 a3 ; 1 set2 a3 6 add2 f1 a3 f1 set2 a1 1 set2 a3 6 ; 保存「变量 code subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 4 set2 a3 4 ; 保存「变量 2」x subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 0 set2 a3 2 ; 保存「变量 3」y subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; .call @function_draw_char set2 a3 6 subtract2 f1 a3 a3 ; 2 set2 a3 2 add2 f1 a3 f1 set2 a1 2 set2 a3 6 ; 保存「变量 code subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 8 set2 a3 4 ; 保存「变量 2」x subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 0 set2 a3 2 ; 保存「变量 3」y subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; .call @function_draw_char set2 a3 6 subtract2 f1 a3 a3 ;3 set2 a3 6 add2 f1 a3 f1 set2 a1 3 set2 a3 6 ; 保存「变量 code subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 12 set2 a3 4 ; 保存「变量 2」x subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; set2 a1 0 set2 a3 2 ; 保存「变量 3」y subtract2 f1 a3 a3 ; save_from_register2 a1 a3 ; .call @function_draw_char set2 a3 6 subtract2 f1 a3 a3 halt .memory 64512 .data 92 214 116 0 238 16 238 0 132 254 128 0 254 146 242 0 """ asm = func_asm + asm # AxePU = x16vm.AxePU # cpu = AxePU(memory) # x16vm._run(cpu) memory = x16asm.machine_code(asm) x16vm.run(memory) canvas = x16vm.Canvas(20) canvas.draw(memory[65024:])