Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <stdio.h>
- #include <errors.h>
- #include <string.h>
- #define STACK_SIZE 65536
- #define REGISTERS 8
- #define ADDRESS_SPACE_SIZE 32768 // Equal to 2^15
- #define MODM & 32767
- int DEBUG = 0;
- int VDEBUG = 0;
- #define debug_log if (DEBUG)
- #define vdebug_log if (VDEBUG)
- int stack[STACK_SIZE];
- int stack_ptr = 0;
- int registers[REGISTERS];
- unsigned long *mem_ptr;
- unsigned long *mem_start;
- int main(int argc, char* argv[]);
- unsigned long read(FILE *file_pointer);
- int process_opcodes();
- unsigned long convert_value();
- unsigned long convert_value() {
- unsigned long reg_val = *mem_ptr;
- mem_ptr++;
- unsigned long value = 0;
- if (reg_val < ADDRESS_SPACE_SIZE) {
- value = reg_val;
- if (VDEBUG)
- printf("Value Entered: %ld\n", value);
- }
- else {
- value = registers[reg_val MODM];
- vdebug_log printf("Accessing register %ld, value %ld\n", reg_val MODM, value);
- }
- return value % ADDRESS_SPACE_SIZE;
- }
- int process_opcodes() {
- long opcode = *mem_ptr;
- mem_ptr++;
- vdebug_log printf("Opcode: %ld \t\t\t", opcode);
- switch(opcode) {
- case 0:
- debug_log printf("Memory Address: %lld\n", (mem_ptr - mem_start));
- return -1;
- break;
- case 1: {
- unsigned long set_reg = *mem_ptr MODM;
- mem_ptr++;
- unsigned long value = convert_value();
- debug_log printf("SET %ld, %ld\n", set_reg, value);
- registers[set_reg] = value;
- break;
- }
- case 2: {
- unsigned long value = convert_value();
- stack_ptr++;
- if (stack_ptr == STACK_SIZE) {
- printf("Stack Overflow \n");
- stack_ptr--;
- return -1;
- break;
- }
- debug_log printf("PUSH %lu\n", value);
- stack[stack_ptr] = value;
- break;
- }
- case 3: {
- unsigned long reg = *mem_ptr % ADDRESS_SPACE_SIZE;
- mem_ptr++;
- if (stack_ptr == 0) {
- printf("Stack Underflow. \n");
- return -1;
- break;
- }
- registers[reg] = stack[stack_ptr];
- stack[stack_ptr] = 0;
- stack_ptr--;
- debug_log printf("POP %lu\n", reg);
- break;
- }
- case 4: {
- unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
- mem_ptr++;
- unsigned long b = convert_value();
- unsigned long c = convert_value();
- registers[a] = (b == c);
- debug_log printf("EQ %ld, %ld, %ld\n", a, b, c);
- vdebug_log printf("New value of %ld register: %d\n", a, registers[a]);
- break;
- }
- case 5: {
- unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
- mem_ptr++;
- unsigned long b = convert_value();
- unsigned long c = convert_value();
- registers[a] = (b > c);
- debug_log printf("GT %ld, %ld, %ld\n", a, b, c);
- vdebug_log printf("New value of %ld register: %d", a, registers[a]);
- break;
- }
- case 6: {
- unsigned long offset = *mem_ptr;
- mem_ptr++;
- debug_log printf("JMP %ld\n", (offset * 2));
- mem_ptr = mem_start + offset;
- break;
- }
- case 7: {
- unsigned long value = convert_value();
- unsigned long offset = *mem_ptr;
- mem_ptr++;
- debug_log printf("JT %ld, %ld\n", value, (offset * 2));
- if (!value)
- break;
- mem_ptr = mem_start + offset;
- break;
- }
- case 8: {
- unsigned long value = convert_value();
- unsigned long offset = *mem_ptr;
- mem_ptr++;
- debug_log printf("JF %ld, %ld\n", value, (offset * 2));
- if (value)
- break;
- mem_ptr = mem_start + offset;
- break;
- }
- case 9: {
- unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
- mem_ptr++;
- unsigned long b = convert_value();
- unsigned long c = convert_value();
- registers[a] = (b + c) MODM;
- debug_log printf("ADD %ld, %ld, %ld\n", a, b, c);
- vdebug_log printf("New value of %ld register: %d", a, registers[a]);
- break;
- }
- case 10: {
- unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
- mem_ptr++;
- unsigned long b = convert_value();
- unsigned long c = convert_value();
- registers[a] = (b * c) MODM;
- debug_log printf("MUL %ld, %ld, %ld\n", a, b, c);
- vdebug_log printf("New value of %ld register: %d", a, registers[a]);
- break;
- }
- case 11: {
- unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
- mem_ptr++;
- unsigned long b = convert_value();
- unsigned long c = convert_value();
- registers[a] = (b % c);
- debug_log printf("MOD %ld, %ld, %ld\n", a, b, c);
- vdebug_log printf("New value of %ld register: %d", a, registers[a]);
- break;
- }
- case 12: {
- unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
- mem_ptr++;
- unsigned long b = convert_value();
- unsigned long c = convert_value();
- registers[a] = (b & c) MODM;
- debug_log printf("AND %ld, %ld, %ld\n", a, b, c);
- vdebug_log printf("New value of %ld register: %d", a, registers[a]);
- break;
- }
- case 13: {
- unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
- mem_ptr++;
- unsigned long b = convert_value();
- unsigned long c = convert_value();
- registers[a] = (b | c) MODM;
- debug_log printf("OR %ld, %ld, %ld\n", a, b, c);
- vdebug_log printf("New value of %ld register: %d", a, registers[a]);
- break;
- }
- case 14: {
- unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
- mem_ptr++;
- unsigned long b = convert_value();
- registers[a] = (~b) MODM;
- debug_log printf("NOT %ld, %ld\n", a, b);
- vdebug_log printf("New value of %ld register: %d", a, registers[a]);
- break;
- }
- case 15: {
- unsigned long a = *mem_ptr % ADDRESS_SPACE_SIZE;
- mem_ptr++;
- unsigned long b = convert_value();
- registers[a] = *(mem_start + b);
- debug_log printf("RMEM %lu, %lu\n", a, b);
- break;
- }
- case 16: {
- unsigned long a = convert_value();
- unsigned long b = convert_value();
- *(mem_start + a) = b;
- debug_log printf("WMEM %lu, %lu\n", a, b);
- break;
- }
- case 17: {
- unsigned long call_mov = convert_value();
- stack_ptr++;
- if (stack_ptr == STACK_SIZE) {
- printf("Stack Overflow \n");
- stack_ptr--;
- return -1;
- break;
- }
- debug_log printf("CALL %ld\n", call_mov);
- vdebug_log printf("Stack: ");
- stack[stack_ptr] = mem_ptr - mem_start;
- for (int i = 0; i <= stack_ptr; i++)
- vdebug_log printf("%d, ", stack[i]);
- mem_ptr = call_mov + mem_start;
- break;
- }
- case 18: {
- if (stack_ptr == 0) {
- printf("Stack Underflow. \n");
- return -1;
- break;
- }
- int stack_top = stack[stack_ptr];
- stack[stack_ptr] = 0;
- stack_ptr--;
- mem_ptr = stack_top + mem_start;
- debug_log printf("RET \n");
- break;
- }
- case 19:
- char data = (char)(*mem_ptr);
- mem_ptr++;
- printf("%c", data);
- break;
- case 20: {
- unsigned long reg = (*mem_ptr) MODM;
- mem_ptr++;
- registers[reg] = getchar();
- debug_log printf("IN %lu", reg);
- while(getchar() != '\n');
- }
- case 21:
- break;
- default:
- debug_log printf("Unrecognised Opcode: %ld\n", opcode);
- debug_log printf("Memory Address: %lld\n", (mem_ptr - mem_start));
- return -1;
- break;
- }
- return 0;
- }
- unsigned long read(FILE *file_pointer) {
- unsigned long low = fgetc(file_pointer);
- unsigned long high = fgetc(file_pointer);
- vdebug_log printf("read value: %lu \t\t\t", (low + (high << 4)));
- vdebug_log printf("Memory address: %lu\n", ftell(file_pointer));
- return (low + (high << 8));
- }
- int main(int argc, char* argv[]) {
- for (int i = 0; i < REGISTERS; i++) {
- registers[i] = 0;
- vdebug_log printf("Zeroed register %d\n", i);
- }
- if (argc < 2) {
- printf("usage: %s binary.exe [-v/-vv]", argv[0]);
- return 1;
- }
- char *file_name = *(argv + 1);
- // Open file to read
- FILE *file_pointer;
- errno_t error = fopen_s(&file_pointer, file_name, "rb");
- if (error != 0) {
- printf("%s could not be opened", file_name);
- printf("Error: %d", error);
- return 1;
- }
- if (argc >= 3) {
- if (strcmp(*(argv + 2), "-vv") == 0) {
- printf("Turning on verbose debug mode\n");
- VDEBUG = 1;
- } else if (strcmp(*(argv + 2), "-v") == 0) {
- printf("Turning on debugging mode\n");
- DEBUG = 1;
- } else {
- printf("Usage: %s binary.exe [-v/-vv]", *argv);
- return 1;
- }
- }
- // Get size of binary
- fseek(file_pointer, 0, SEEK_END);
- long size = ftell(file_pointer);
- FILE *file_start = file_pointer;
- fseek(file_pointer, 0, SEEK_SET);
- printf("File size: %ld\n", size);
- // read binary into memory
- int address_space = size/2;
- unsigned long *memory = malloc(size* 2);
- printf("Allocated %ld bytes into memory", size * 2);
- mem_ptr = memory;
- mem_start = memory;
- for (int i = 0; i < address_space; i++) {
- unsigned long temp = read(file_pointer);
- *memory = temp;
- memory++;
- }
- // size = 1000;
- while (process_opcodes() != -1) {
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment