Понимание хранения / загрузки и памяти в простой виртуальной машине C - PullRequest
0 голосов
/ 29 марта 2020

Я близок к концу простого виртуального компьютера, который я создаю в C, и столкнулся с препятствием в моем понимании инструкций сохранения / загрузки, а также того, как значения фактически «хранятся» в памяти. На практике, выполняя инструкции загрузки и сохранения с помощью приведенных ниже команд, они, кажется, работают правильно, и я могу загружать / сохранять значения в своих регистрах, но когда я выполняю команду interrupt 1 для распечатки памяти, единственное значение, которое кажется, распечатывается это первое значение i stored на "memory". Я храню неправильно или просто распечатываю неправильно или это нечто большее? Полный код приведен ниже для полноты, а также основные моменты проблемных областей.

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();
}

Функция загрузки и сохранения + печать стека

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");
                }
            }

Токовый вход

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"

Токовый выход памяти, выделяется жирным шрифтом около «Хранимых 4», но нет 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
...