zongors-reality-engine/docs/dis-like-mem2mem/udis_vm.c

70 lines
1.9 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#define MEMORY_SIZE 65536 // 64KB memory (adjustable)
uint32_t memory[MEMORY_SIZE]; // Memory array
typedef enum {
OP_ADD, // dest = src1 + src2
OP_MOV, // dest = src1
OP_JMP, // jump to address
OP_HALT // terminate execution
} Opcode;
void run_vm() {
uint32_t pc = 0; // Program counter
while (1) {
// Fetch instruction
Opcode opcode = memory[pc];
uint32_t src1_addr = memory[pc + 1];
uint32_t src2_addr = memory[pc + 2];
uint32_t dest_addr = memory[pc + 3];
pc += 4; // Advance to next instruction
// Validate addresses (safety check)
if (src1_addr >= MEMORY_SIZE || src2_addr >= MEMORY_SIZE || dest_addr >= MEMORY_SIZE) {
printf("Invalid memory address!\n");
exit(1);
}
// Execute instruction
switch (opcode) {
case OP_ADD:
memory[dest_addr] = memory[src1_addr] + memory[src2_addr];
break;
case OP_MOV:
memory[dest_addr] = memory[src1_addr];
break;
case OP_JMP:
pc = src1_addr; // Jump to address
break;
case OP_HALT:
return;
default:
printf("Unknown opcode: %d\n", opcode);
exit(1);
}
}
}
int main() {
// Initialize memory
memory[0] = OP_ADD; // Opcode
memory[1] = 100; // A (src1)
memory[2] = 101; // B (src2)
memory[3] = 102; // C (dest)
memory[100] = 5; // Value of A
memory[101] = 7; // Value of B
memory[4] = OP_HALT; // Terminate after ADD
run_vm();
printf("Result at address 102: %u\n", memory[102]); // Output: 12
return 0;
}