Skip to content

Commit

Permalink
Add some more comments in the assembler program
Browse files Browse the repository at this point in the history
  • Loading branch information
wmvanvliet committed May 31, 2022
1 parent d6a311f commit 69a26d0
Showing 1 changed file with 33 additions and 17 deletions.
50 changes: 33 additions & 17 deletions assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import sys
import struct

instruction_to_num = {
opcodes = {
'nop': 0,
'lda': 1,
'add': 2,
Expand All @@ -15,14 +15,19 @@
'out': 14,
'hlt': 15,
}
num_to_instruction = {v: k for k, v in instruction_to_num.items()}
num_to_instruction = {v: k for k, v in opcodes.items()}


def assemble(program_code, verbose=False):
# Keep track of the memory addresses at which labels are defined
labels = dict()
output = list()

# Parse file

# Step 1: Parse file, producing a list of tokens. Each token represents one
# byte in memory. These tokens will be translated into binary code during
# the next step.
tokens = list()

for line_nr, line in enumerate(program_code.split('\n')):
def error(msg):
print(f'L{line_nr + 1}: {line}')
Expand All @@ -36,7 +41,7 @@ def error(msg):
# Deal with labels:
if ':' in line:
label, line = line.split(':', 1)
labels[label.strip().lower()] = len(output)
labels[label.strip().lower()] = len(tokens)

line = line.strip()
if len(line) == 0:
Expand All @@ -47,7 +52,7 @@ def error(msg):
if instruction in ['nop', 'out', 'hlt']:
if len(params) > 0:
error(f'{instruction} takes no parameters')
output.append((instruction,))
tokens.append((instruction,))
else:
if len(params) != 1:
error(f'{instruction} takes a single parameter')
Expand All @@ -57,28 +62,39 @@ def error(msg):
if not (0 <= param <= 255):
error('Parameter must be 0-255')

output.append((instruction,param))
tokens.append((instruction, param))

# Resolve labels and convert to binary
# Convert each token to a binary number
bin_output = list()
for line in output:
instruction = line[0]
for token in tokens:
instruction = token[0]

# The "db" pseudo-instruction places the parameter in memory
if instruction == 'db':
bin_line = 0
else:
bin_line = instruction_to_num[instruction] << 4
if len(line) == 2:
param = line[1]
bin_output.append(token[1])
continue

# Get the opcode for the instruction and place it into the upper 4 bits
# of the memory.
bin_line = opcodes[instruction] << 4

# If the instruction has a parameter, place it into the lower 4 bits of
# the memory.
if len(token) == 2:
param = token[1]
# Parameter could be a label, in which case, translate it into the
# memory address it refers to.
if type(param) == str:
param = labels[param]
# Place parameter value into the lower 4 bits
bin_line += param
bin_output.append(bin_line)

# Create human readable version of the memory contents
human_readable = list()
addr_to_label = {v: k for k, v in labels.items()}
for addr, (o, b) in enumerate(zip(output, bin_output)):
i = ' '.join([str(x) for x in o])
for addr, (t, b) in enumerate(zip(tokens, bin_output)):
i = ' '.join([str(x) for x in t])
label = addr_to_label.get(addr, '')
if label:
label = f'({label})'
Expand Down

0 comments on commit 69a26d0

Please sign in to comment.