OneCompiler

pass 11

1635

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.")