I am nearing the ends of a simple vm i am creating in C and have hit a roadblock in my understanding of the store/load instructions as well as how the values are actually "Stored" in memory. In practice when doing a load and store instruction with the below commands they do seem to work properly and i can load/store values into my registers but when i do an interrupt 1
command to print out memory the only value it seems to print out is the first value i stored
onto the "memory"
. Am i storing incorrectly or just printing out incorrectly or is it something more? Full code posted below for completeness along with highlights of the trouble areas.
MAIN.C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#define MAXMEM 1024
#define NUM_REGS 16
int regs[ NUM_REGS];
uint8_t memory[MAXMEM];
uint8_t fetchresult[5];
bool Call = false;
int pc = 0;
int opcode = 0;
int reg1 = 0;
int reg2 = 0;
int reg3 = 0;
//int reg15 = 0;
int imm = 0;
int br1 = 0;
int br2 = 0;
int stackinst = 0;
int br_op = 0;
uint8_t callnxt = 0;
int sp = -1;
int stored = 0;
void showRegs();
void printStack();
size_t loads (char *filename)
{
FILE *file = fopen(filename, "rb");
if(!file) {
perror("Failed to read file");
exit( EXIT_FAILURE);
}
fseek(file, 0, SEEK_END);
int filesize = ftell(file);
//printf("filesize is %d\n", filesize);
sp = filesize;
rewind(file);
return fread(memory, sizeof(memory), filesize, file);
}
void fetch(){
//printf("%02x\n", memory[pc]);
fetchresult[0] = memory[pc];
fetchresult[1] = memory[pc+1];
fetchresult[2] = memory[pc+2];
fetchresult[3] = memory[pc+3];
fetchresult[4] = memory[pc+4];
pc+=2;
}
int running = 1; // shows vm is running until flag is 0
void decode () {
opcode = (fetchresult[0]) >> 4;
//printf("opcode is %d\n", opcode);
reg1 = (fetchresult[0])&0xf;
//printf("reg1 is %d\n", reg1);
reg2 = (fetchresult[1]) >> 4;
//printf("reg2 is %d\n", reg2);
reg3 = (fetchresult[1])&0xf;
//printf("reg3 is %d\n", reg3);
imm = (fetchresult[1] & 0xFF);
//printf("immediate value is %d\n", imm);
br1 = (fetchresult[2] << 8 | fetchresult[3]);
//printf("br1 value is %d\n", br1);
br2 = (fetchresult[1] << 16 | br1);
//printf("br2 value is %d\n", br2);
stackinst = (fetchresult[1] >> 6);
//printf("stackinst value is %d\n", stackinst);
br_op = (fetchresult[0] &0xf);
//printf("br_op value is %d\n", br_op);
callnxt = (fetchresult[4]);
//printf("Callnxt is %02x\n", callnxt);
}
void eval() {
switch (opcode)
{
case 0:
printf("halt\n");
running = 0;
break;
case 11:
printf("Move r%d with value of %d\n", reg1, imm);
regs[reg1] = imm;
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 1:
printf("add r%d r%d r%d\n", reg1, reg2, reg3);
regs[reg3] = regs[reg1] + regs[reg2];
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 2:
printf("and r%d r%d r%d\n", reg1, reg2, reg3);
regs[reg3] = regs[reg1] & regs[reg2];
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 3:
printf("divide r%d r%d r%d\n", reg1, reg2, reg3);
regs[reg3] = regs[reg1] / regs[reg2];
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 4:
printf("multiply r%d r%d r%d\n", reg1, reg2, reg3);
regs[reg3] = regs[reg1] * regs[reg2];
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 5:
printf("subtract r%d r%d r%d\n", reg1, reg2, reg3);
regs[reg3] = regs[reg1] - regs[reg2];
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 6:
printf("or r%d r%d r%d\n", reg1, reg2, reg3);
regs[reg3] = regs[reg1] | regs[reg2];
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 7:
switch(br_op)
{
case 0: // branchifless
if(regs[reg2] < regs[reg3]){
pc += 2*br1;
}
break;
case 1: //branch if less or equal
if(regs[reg2] <= regs[reg3]){
pc += 2*br1;
}
break;
case 2: // branch if equal
if(regs[reg2] == regs[reg3]){
pc += 2*br1;
}
break;
case 3: // branch if not equal
if(regs[reg2] != regs[reg3]){
pc += 2*br1;
}
break;
case 4: // branch if greater then
if(regs[reg2] > regs[reg3]){
pc += 2*br1;
}
break;
case 5: // branch if greater than or equal
if(regs[reg2] >= regs[reg3]){
pc += 2*br2;
}
break;
case 6: // call & return
printf("Call %d\n", br2);
regs[15] = pc + 2;
printf("Reg 15 is %02x\n", regs[15]);
Call = true;
pc += 2*br2;
break;
case 7: // jump X
printf("Jump %d\n", br1);
pc += 2*br2;
}
break;
case 8: // load TO DO
sp;
int loaded = sp + (regs[reg3] + (imm * 2));
regs[reg1] = memory[loaded];
printf("Loaded value is %d\n", regs[reg1]);
sp = sp--;
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 9: // store TO DO
sp = sp++;
stored = sp + (regs[reg3] + (imm * 2));
sp = stored;
memory[stored] = regs[reg1];
printf("Stored value is %d\n", memory[stored]);
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 10: // pop/push/return TO DO
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 12: // interrupt TO DO
switch(br_op){
case 0:
showRegs();
exit(0);
break;
case 1:
printStack();
exit(0);
break;
}
break;
}
}
void showRegs() {
int i;
for (i=0; i< NUM_REGS; i++){
printf("register %d is %d", i, regs[i] );
printf("\n");
}
}
void printStack() {
//printf("Values in memory? %d\n", memory[sp]);
for(int i = 0; i < sp; i++) {
printf("0x%02x ", memory[i]);
if((i + 1) %4 == 0) {
printf("\n");
}
}
if(sp != 0) {
printf("\n");
}
}
void run(){
while(running){
//showRegs();
fetch();
decode();
eval();
}
showRegs();
}
int main(int argc, char **argv) {
if(argc <= 1){
printf("No File Found\n");
return -1;
}
char *filename = argv[1];
loads(filename);
//sp++;
//printf("SP points to %d in memory\n", memory[sp]);
run();
}
Load and Store Function + Stack Print
case 8: // load TO DO
sp;
int loaded = sp + (regs[reg3] + (imm * 2));
regs[reg1] = memory[loaded];
printf("Loaded value is %d\n", regs[reg1]);
sp = sp--;
if(Call == true){
pc = regs[15];
Call = false;
}
break;
case 9: // store TO DO
sp = sp++;
stored = sp + (regs[reg3] + (imm * 2));
sp = stored;
memory[stored] = regs[reg1];
printf("Stored value is %d\n", memory[stored]);
if(Call == true){
pc = regs[15];
Call = false;
}
void printStack() {
//printf("Values in memory? %d\n", memory[sp]);
for(int i = 0; i < sp; i++) {
printf("0x%02x ", memory[i]);
if((i + 1) %4 == 0) {
printf("\n");
}
}
if(sp != 0) {
printf("\n");
}
}
Current Input
b604 b702 9622 9743 c100
(Move 4 to R6, Move 2 to R7, Store R6 R2 2, Store R7 R4 3, Interrupt 1)
Description of Store - "stores r6’s value into the memory pointed to by r2 plus 4 bytes"
Current Output Of Memory, bolding stars about the "Stored 4" But there is no 2??
0xb6 0x04 0xb7 0x02
0x96 0x22 0x97 0x43
0xc1 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 **0x04** 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00