Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
3.3 kB
1
Indexable
Never
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <unordered_map>
#include <iomanip>

using namespace std;

// Structure to hold opcode information
struct Opcode {
    string mnemonic;
    string opcode;
};

// Symbol table to hold labels and their addresses
unordered_map<string, int> symbolTable;

// Opcode table for the assembler
unordered_map<string, Opcode> opcodeTable = {
    {"MOV", {"MOV", "B8"}},
    {"ADD", {"ADD", "01"}},
    {"SUB", {"SUB", "29"}},
    {"JMP", {"JMP", "EB"}}
};

// Utility function to trim whitespace
string trim(const string &str) {
    size_t first = str.find_first_not_of(' ');
    if (first == string::npos) return "";
    size_t last = str.find_last_not_of(' ');
    return str.substr(first, (last - first + 1));
}

// First pass: Build the symbol table
void firstPass(const vector<string> &sourceCode) {
    int address = 0;

    for (const auto &line : sourceCode) {
        istringstream iss(line);
        string label, mnemonic, operand;

        // Extract label if present
        getline(iss, label, ':');
        if (iss.peek() == ' ' || iss.peek() == '\t' || iss.peek() == '\n') {
            label = trim(label);
        } else {
            iss.seekg(0);
            label.clear();
        }

        // Extract mnemonic and operand
        iss >> mnemonic >> operand;

        if (!label.empty()) {
            symbolTable[label] = address;
        }

        if (!mnemonic.empty() && opcodeTable.find(mnemonic) != opcodeTable.end()) {
            address += 2; // Assuming fixed length instructions for simplicity
        }
    }
}

// Second pass: Generate machine code
void secondPass(const vector<string> &sourceCode, vector<string> &machineCode) {
    for (const auto &line : sourceCode) {
        istringstream iss(line);
        string label, mnemonic, operand;

        // Extract label if present
        getline(iss, label, ':');
        if (iss.peek() == ' ' || iss.peek() == '\t' || iss.peek() == '\n') {
            label = trim(label);
        } else {
            iss.seekg(0);
            label.clear();
        }

        // Extract mnemonic and operand
        iss >> mnemonic >> operand;

        if (!mnemonic.empty() && opcodeTable.find(mnemonic) != opcodeTable.end()) {
            string opcode = opcodeTable[mnemonic].opcode;
            if (symbolTable.find(operand) != symbolTable.end()) {
                int address = symbolTable[operand];
                stringstream ss;
                ss << opcode << " " << hex << address;
                machineCode.push_back(ss.str());
            } else {
                machineCode.push_back(opcode + " " + operand);
            }
        }
    }
}

int main() {
    // Example assembly source code
    vector<string> sourceCode = {
        "START: MOV AX, 1234",
        "       ADD AX, BX",
        "LOOP:  SUB AX, 1",
        "       JMP LOOP"
    };

    firstPass(sourceCode);

    vector<string> machineCode;
    secondPass(sourceCode, machineCode);

    cout << "Symbol Table:" << endl;
    for (const auto &entry : symbolTable) {
        cout << entry.first << " : " << hex << entry.second << endl;
    }

    cout << "\nMachine Code:" << endl;
    for (const auto &line : machineCode) {
        cout << line << endl;
    }

    return 0;
}
Leave a Comment