pass 11
import os
Define the directory where files will be saved
output_directory = "assembler_output"
os.makedirs(output_directory, exist_ok=True)
Opcode table for the pseudo-machine
opcode_table = {
'LDA': '00', # Load Accumulator
'STA': '01', # Store Accumulator
'ADD': '02', # Add to Accumulator
'SUB': '03', # Subtract from Accumulator
'MUL': '04', # Multiply Accumulator
'DIV': '05', # Divide Accumulator
'HLT': '06', # Halt
}
Example assembler code
assembler_code = [
"START 100",
"LDA ALPHA",
"ADD BETA",
"STA GAMMA",
"HLT",
"ALPHA DC 5",
"BETA DC 10",
"GAMMA DS 1",
"END"
]
Data structures
symbol_table = {} # Stores symbols and their memory addresses
location_counter = 0 # Tracks memory locations
location_counter_log = [] # Stores the value of the location counter for each line
literal_table = {} # Stores literals, if any
def pass_one(assembler_code):
global location_counter
start_address = 0
symbol_table.clear()
location_counter_log.clear()
location_counter = 0
# Pass I: Process each line of the code
for line in assembler_code:
tokens = line.split()
# Handle 'START' directive to set starting address
if tokens[0] == 'START' and len(tokens) > 1:
start_address = int(tokens[1])
location_counter = start_address
location_counter_log.append((line, location_counter))
continue
# Handle 'END' directive to stop processing
if tokens[0] == 'END':
break
# Log current line and location counter
location_counter_log.append((line, location_counter))
# If a label exists, add it to the symbol table with current location counter
if len(tokens) > 1 and (tokens[1] in opcode_table or tokens[1] in ['DC', 'DS']):
label = tokens[0]
symbol_table[label] = location_counter
# Update location counter based on instruction or directive type
if tokens[0] in opcode_table: # Normal opcode instruction
location_counter += 1
elif tokens[0] == 'DC': # Data constant, occupy one memory location
location_counter += 1
elif tokens[0] == 'DS': # Data space (reserve memory)
location_counter += int(tokens[1]) # Reserve specified space
return symbol_table, location_counter_log, literal_table
Execute Pass I to generate symbol table and location counter log
symbol_table, location_counter_log, literal_table = pass_one(assembler_code)
Write symbol table to a file
with open(os.path.join(output_directory, "symbol_table.txt"), "w") as f:
f.write("Symbol Table:\n")
for symbol, address in symbol_table.items():
f.write(f"{symbol}: {address}\n")
Write location counter log to a file
with open(os.path.join(output_directory, "location_counter_log.txt"), "w") as f:
f.write("Location Counter Log:\n")
for line, lc in location_counter_log:
f.write(f"{line} -> LC: {lc}\n")
Write literal table to a file (if empty, write a placeholder message)
with open(os.path.join(output_directory, "literal_table.txt"), "w") as f:
if literal_table:
f.write("Literal Table:\n")
for literal, address in literal_table.items():
f.write(f"{literal}: {address}\n")
else:
f.write("Literal Table is empty (no literals found in Pass I).\n")
print(f"Output files have been generated in the '{output_directory}' directory.")