Skip to content

Instantly share code, notes, and snippets.

@dmateos
Created May 16, 2024 05:40
Show Gist options
  • Save dmateos/00291b31885c5072c847c5cfffae9b4c to your computer and use it in GitHub Desktop.
Save dmateos/00291b31885c5072c847c5cfffae9b4c to your computer and use it in GitHub Desktop.
tinyvm.c
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define PROGRAM_SIZE 1024
enum INSTRUCTIONS {
ADD = 0x01,
SUB,
};
typedef struct {
uint32_t *program_data;
uint32_t *ip;
uint32_t reg0;
} VM_T;
void assemble_file(const char *file) {
char opcode[32];
int parameter;
FILE *fp, *new_fp;
uint32_t opcode_b;
bool write = false;
fp = fopen(file, "r");
if (!fp) {
printf("could not open file %s\n", file);
return;
}
new_fp = fopen("output", "wb");
if (!new_fp) {
printf("could not open file output\n");
fclose(fp);
return;
}
while (fscanf(fp, "%s %d\n", opcode, &parameter) != EOF) {
printf("opcode: %s, parameter: %d\n", opcode, parameter);
if (strcmp(opcode, "ADD") == 0) {
printf("ADD found\n");
opcode_b = ADD;
write = true;
} else if (strcmp(opcode, "SUB") == 0) {
printf("SUB found\n");
opcode_b = SUB;
write = true;
} else {
printf("unknown opcode\n");
}
if (write) {
fwrite(&opcode_b, sizeof(uint32_t), 1, new_fp);
fwrite(&parameter, sizeof(uint32_t), 1, new_fp);
write = false;
}
}
fclose(fp);
fclose(new_fp);
}
void print_vm_state(VM_T *vm) {
printf("\nVM State:\n");
printf("reg0: %d\n", vm->reg0);
printf("ip: %p\n", vm->ip);
printf("*ip: %d\n\n", *vm->ip);
return;
}
void run_vm(VM_T *vm) {
while (true) {
switch (*vm->ip) {
case ADD:
printf("found add!\n");
vm->ip++;
printf("parameter: %d\n", *vm->ip);
vm->reg0 += *vm->ip;
vm->ip++;
print_vm_state(vm);
break;
case SUB:
printf("found sub!\n");
vm->ip++;
printf("parameter: %d\n", *vm->ip);
vm->reg0 -= *vm->ip;
vm->ip++;
print_vm_state(vm);
break;
}
}
}
void init_vm(VM_T *vm, const char *file) {
FILE *fp = fopen(file, "rb");
uint32_t length;
if (!fp) {
printf("could not open file %s\n", file);
return;
}
memset(vm, 0, sizeof(VM_T));
vm->program_data = malloc(PROGRAM_SIZE * sizeof(uint32_t));
memset(vm->program_data, 0, PROGRAM_SIZE * sizeof(uint32_t));
vm->ip = vm->program_data;
fseek(fp, 0, SEEK_END);
length = ftell(fp);
fseek(fp, 0, SEEK_SET);
fread(vm->program_data, sizeof(uint32_t), length / sizeof(uint32_t), fp);
fclose(fp);
}
void free_vm(VM_T *vm) {
free(vm->program_data);
return;
}
int main() {
VM_T vm;
assemble_file("test.s");
init_vm(&vm, "output");
print_vm_state(&vm);
run_vm(&vm);
free_vm(&vm);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment