diff options
Diffstat (limited to 'lab1/lab1asm.py')
| -rw-r--r-- | lab1/lab1asm.py | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/lab1/lab1asm.py b/lab1/lab1asm.py new file mode 100644 index 0000000..ce1df5e --- /dev/null +++ b/lab1/lab1asm.py @@ -0,0 +1,79 @@ +import sys + +OPS = { + "load": 0, + "store": 1, + "add": 2, + "sub": 3, + "and": 4, + "lsr": 5, + "bra": 6, + "bne": 7, + "halt": 8, + "cmp": 9, + "bge": 10, + "beq": 11, +} + +def compile(lines): + addr = 0 + labels = {} + compiled = [] + for line in lines: + if not line: + # empty line, ignore + continue + if line.startswith(";"): + # comment + continue + if line.endswith(":"): + # label + labels[line.split(":")[0]] = addr + continue + match line.split(" "): + case [inst, gr, m, *adr]: + if int(m) == 1: + assert adr == [] + compiled.append("{:02x}: {:01x}{:01x}{:02x}".format( + addr, + OPS[inst], + int(gr) * 4 + int(m), + int(adr[0], 16) if int(m) != 1 else 0, + )) + case [inst, label]: + assert inst in ("bra", "bne", "bge", "beq") + compiled.append("{:02x}: {:01x}0<{}>".format( + addr, + OPS[inst], + label, + )) + case ["halt"]: + compiled.append("{:02x}: {:01x}000".format(addr, OPS["halt"])) + case [oper]: + compiled.append("{:02x}: {:04x}".format(addr, int(oper, 16))) + case _: + compiled.append(" !!!", line) + assert False + addr += 1 + + linked = [] + for line_nr, line in enumerate(compiled): + for label, label_nr in labels.items(): + rel_pos = (label_nr - line_nr + 0xff) & 0xff + line = line.replace(f"<{label}>", f"{rel_pos:02x}") + linked.append(line) + + return linked, labels + + +def write(prog, labels): + prog_pad = 0x100 - len(prog) + prog = "\n".join(prog + [f"{len(prog)+n:02x}: 0000" for n in range(prog_pad)]) + + print("PM:") + print(prog) + #print("\n".join(["{}: {:02x}".format(*label) for label in labels.items()]), file=sys.stderr) + + +if __name__ == "__main__": + write(*compile([line.strip() for line in sys.stdin])) |
