#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
struct VirtualMachine {
int registers[7] = {0};
int programCounter = 0; // Initialize program counter to 0
int flags[4] = {0};
int memory[64] = {0};
};
void updateFlags(VirtualMachine& vm, int result) {
vm.flags[0] = (result > 127) ? 1 : 0;
vm.flags[1] = (result < -128) ? 1 : 0;
vm.flags[2] = (result > 127 || result < -128) ? 1 : 0;
vm.flags[3] = (result == 0) ? 1 : 0;
}
void mov(VirtualMachine& vm, char src, char dst) {
if (src == '#') {
vm.registers[dst - '0'] = dst - '0';
} else if (src >= '0' && src <= '6' && dst >= '0' && dst <= '6') {
vm.registers[dst - '0'] = vm.registers[src - '0'];
}
}
void inc(VirtualMachine& vm, char reg) {
if (reg >= '0' && reg <= '6') {
int result = vm.registers[reg - '0'] + 1;
vm.registers[reg - '0'] = result;
updateFlags(vm, result);
}
}
void in(VirtualMachine& vm, char reg) {
if (reg >= '0' && reg <= '6') {
std::cout << "Enter a value for register R" << reg - '0' << ": ";
std::cin >> vm.registers[reg - '0'];
updateFlags(vm, vm.registers[reg - '0']);
} else {
std::cerr << "Invalid register: R" << reg - '0' << std::endl;
}
}
void out(const VirtualMachine& vm, char reg) {
if (reg >= '0' && reg <= '6') {
std::cout << "Value in register R" << reg - '0' << ": " << vm.registers[reg
- '0'] << std::endl;
} else {
std::cerr << "Invalid register: R" << reg - '0' << std::endl;
}
}
void load(VirtualMachine& vm, char reg, char addr) {
if (reg >= '0' && reg <= '6' && addr >= 0 && addr < 64) {
vm.registers[reg - '0'] = vm.memory[addr];
}
}
void add(VirtualMachine& vm, char src, char dst) {
if (src >= '0' && src <= '6' && dst >= '0' && dst <= '6') {
int result = vm.registers[dst - '0'] + vm.registers[src - '0'];
vm.registers[dst - '0'] = result;
updateFlags(vm, result);
}
}
void sub(VirtualMachine& vm, char src, char dst) {
if (src >= '0' && src <= '6' && dst >= '0' && dst <= '6') {
int result = vm.registers[dst - '0'] - vm.registers[src - '0'];
vm.registers[dst - '0'] = result;
updateFlags(vm, result);
}
}
void mul(VirtualMachine& vm, char src, char dst) {
if (src >= '0' && src <= '6' && dst >= '0' && dst <= '6') {
int result = vm.registers[dst - '0'] * vm.registers[src - '0'];
vm.registers[dst - '0'] = result;
updateFlags(vm, result);
}
}
void div(VirtualMachine& vm, char src, char dst) {
if (src >= '0' && src <= '6' && dst >= '0' && dst <= '6' && vm.registers[src -
'0'] != 0) {
int result = vm.registers[dst - '0'] / vm.registers[src - '0'];
vm.registers[dst - '0'] = result;
updateFlags(vm, result);
} else {
std::cerr << "Invalid division operation: Division by zero or invalid
registers." << std::endl;
}
}
void dec(VirtualMachine& vm, char reg) {
if (reg >= '0' && reg <= '6') {
int result = vm.registers[reg - '0'] - 1;
vm.registers[reg - '0'] = result;
updateFlags(vm, result);
}
}
void store(VirtualMachine& vm, char src, char addr) {
if (src >= '0' && src <= '6' && addr >= 0 && addr < 64) {
vm.memory[addr] = vm.registers[src - '0'];
}
}
void storeIndirect(VirtualMachine& vm, char src, char regAddr) {
if (src >= '0' && src <= '6' && regAddr >= '0' && regAddr <= '6') {
int addr = vm.registers[regAddr - '0'];
if (addr >= 0 && addr < 64) {
vm.memory[addr] = vm.registers[src - '0'];
} else {
std::cerr << "Invalid memory address: " << addr << std::endl;
}
} else {
std::cerr << "Invalid register or memory address: R" << src - '0' << ", R"
<< regAddr - '0' << std::endl;
}
}
void executeAssembly(const std::string& filename, VirtualMachine& vm) {
std::ifstream file(filename);
std::string line;
if (file.is_open()) {
while (getline(file, line)) {
char instruction[64];
char op1, op2;
if (sscanf(line.c_str(), "%s %c %c", instruction, &op1, &op2) == 3) {
if (strcmp(instruction, "MOV") == 0) {
mov(vm, op1, op2);
} else if (strcmp(instruction, "ADD") == 0) {
add(vm, op1, op2);
} else if (strcmp(instruction, "INC") == 0) {
inc(vm, op1);
} else if (strcmp(instruction, "IN") == 0) {
in(vm, op1);
} else if (strcmp(instruction, "OUT") == 0) {
out(vm, op1);
} else if (strcmp(instruction, "LOAD") == 0) {
load(vm, op1, op2 - '0');
} else if (strcmp(instruction, "SUB") == 0) {
sub(vm, op1, op2);
} else if (strcmp(instruction, "MUL") == 0) {
mul(vm, op1, op2);
} else if (strcmp(instruction, "DIV") == 0) {
div(vm, op1, op2);
} else if (strcmp(instruction, "DEC") == 0) {
dec(vm, op1);
} else if (strcmp(instruction, "STORE") == 0) {
store(vm, op1, op2 - '0');
} else if (strcmp(instruction, "STORE") == 0 && op2 == '[') {
char regAddr;
if (sscanf(line.c_str(), "%s %c [%c]", instruction, &op1,
®Addr) == 3) {
storeIndirect(vm, op1, regAddr);
} else {
std::cerr << "Invalid STORE instruction format: " << line
<< std::endl;
}
}
}
}
file.close();
} else {
std::cerr << "Unable to open file: " << filename << std::endl;
}
}
void displayState(const VirtualMachine& vm) {
std::cout << "Registers:\n";
for (int i = 0; i < 7; ++i) {
std::cout << "R" << i << ": " << vm.registers[i] << '\t';
}
std::cout << "\nProgram Counter (PC): " << vm.programCounter << '\n';
std::cout << "Flags:\n";
std::cout << "Overflow Flag (OF): " << vm.flags[0] << '\n';
std::cout << "Underflow Flag (UF): " << vm.flags[1] << '\n';
std::cout << "Carry Flag (CF): " << vm.flags[2] << '\n';
std::cout << "Zero Flag (ZF): " << vm.flags[3] << '\n';
std::cout << "\nMemory:\n";
for (int i = 0; i < 64; ++i) {
std::cout << "M" << i << ": " << vm.memory[i] << '\t';
if ((i + 1) % 8 == 0) {
std::cout << '\n';
}
}
std::cout << "#\n";
}
int main() {
VirtualMachine vm;
executeAssembly("test.asm", vm);
displayState(vm);
return 0;
}