Created
October 27, 2017 21:28
-
-
Save v4lli/5d2d05353f22034aa20e2c4ff21cb381 to your computer and use it in GitHub Desktop.
Simple assembler to generate bytecode from asm text instructions for a custom-built microprocessor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# | |
# Valentin Dornauer <valentin@unimplemented.org> | |
# Sun Dec 11 22:11:27 CET 2016 | |
# | |
# Simple assembler to generate bytecode from asm | |
# text instructions for a custom-built microprocessor. | |
# | |
# Usage: tiasm.py <input_file> | |
# Example programm (multiplication 5*3): | |
# | |
# # erster faktor: 5 | |
# LDA #5 | |
# STA 14 | |
# STA 13 | |
# # zweiter faktor: 3 | |
# LDA #3 | |
# STA 15 | |
# SUB #1 | |
# STA 15 | |
# BRZ #6 | |
# LDA 13 | |
# ADD 14 | |
# STA 13 | |
# LDA 15 | |
# JMP 5 | |
# NOP | |
# NOP | |
# NOP | |
import sys | |
import re | |
def generate_mword(lower, upper): | |
return lower | upper << 4 | |
def ascii2mword(input): | |
match = re.match(r"^([A-Za-z]+)\s*([#~]?)([0-9]*)$", input) | |
if not match: | |
print("# ERROR: don't know what to do with '%s'", input) | |
return 0 | |
opcode = match.group(1).upper() | |
is_immediate = len(match.group(2)) > 0 | |
try: | |
immediate_value = int(match.group(3)) | |
except ValueError: | |
immediate_value = None | |
if opcode == "NOP": | |
return 0 | |
elif opcode == "LDA": | |
return generate_mword(0b0001 if is_immediate else 0b0010, | |
immediate_value) | |
elif opcode == "STA": | |
return generate_mword(0b0011, immediate_value) | |
elif opcode == "ADD": | |
return generate_mword(0b0100 if is_immediate else 0b0101, | |
immediate_value) | |
elif opcode == "SUB": | |
return generate_mword(0b0110 if is_immediate else 0b0111, | |
immediate_value) | |
elif opcode == "JMP": | |
return generate_mword(0b1000, immediate_value) | |
elif opcode == "BRZ": | |
return generate_mword(0b1001, immediate_value) | |
elif opcode == "BRC": | |
return generate_mword(0b1010, immediate_value) | |
elif opcode == "BRN": | |
return generate_mword(0b1011, immediate_value) | |
else: | |
print("# ERROR: Unknown instruction %s" % opcode) | |
return 0 | |
if __name__ == "__main__": | |
if len(sys.argv) < 2: | |
print("Usage: tiasm.py <input_file>") | |
input_file = sys.argv[1] | |
with open(input_file) as fh: | |
for line in fh.readlines(): | |
if line.startswith("#"): | |
continue | |
mword = ascii2mword(line.rstrip()) | |
print("# %s" % line.rstrip()) | |
print("{0:08b}".format(mword)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output for example program: