Beispiel #1
0
void printStacktrace()
{
   printStacktrace( std::cerr );
}
int main(int argc, char *argv[])
{
    // Initialize read and write files
    FILE *ifp = fopen(argv[1], "r");
    FILE *ofp = fopen(argv[2], "w+");

    // Exit program if a file was not opened
    if(ifp == NULL) { printf("Input File Not Found\n");  return 0; }
    if(ofp == NULL) { printf("Output File Not Found\n"); return 0; }

    // Register architecture
    int BP = 1; // Base Pointer
    int SP = 0; // Stack Pointer
    int PC = 0; // Program Counter
    instruction *IR; // Instructions (Opcode, Lexi. Level, Parameter)
    int prev;

    // Initialize stack
    int stack[MAX_STACK_HEIGHT];
    memset(stack, 0, MAX_STACK_HEIGHT * sizeof(int));

    // Create and intialize an array of structs
    instruction instructions[MAX_CODE_LENGTH];
    read(ifp, instructions);

    // Close input file
    fclose(ifp);

    // Print the instructions to be executed
    printInstructions(ofp, instructions);

    // Print header for the stacktrace
    fprintf(ofp, "\n\n\t\t\t\t\tPC\tBP\tSP\tStack \nInitial Values \t\t\t\t\t%d\t%d\t%d\n", 0, 1, stack[0]);

    printf("Fetch -> Execute Cycle\n");

    // Fetch -> Execute Cycle
    bool halt = false;
    while(halt == false)
    {
        // Get instruction
        IR = &instructions[PC];

        // Save last program counter
        prev = PC;

        // Set instructions for cleaner usage
        int OP = IR->OP;
        int L = IR->L;
        int M = IR->M;

        switch(OP)
        {
            // LIT - Push value M onto the stack
            case 1:
                SP++;
                stack[SP] = M;
                PC++;
                break;
            /* OPR - Return from a procedure call
             *       or do an ALU op, specified by M */
            case 2:
                switch(M)
                {
                    // Return from a procedure call
                    case 0:
                       SP = BP - 1;
                       PC = stack[SP + 4];
                       BP = stack[SP + 3];
                        break;
                    // NEG - Pop once -> push the negation of the result
                    case 1:
                        stack[SP] = -stack[SP];
                        break;
                    // ADD - Pop twice -> add -> push
                    case 2:
                        SP--;
                        stack[SP] = stack[SP] + stack[SP + 1];
                        break;
                    // SUB - Pop twice -> subtract top value from bottom value -> push
                    case 3:
                        SP--;
                        stack[SP] = stack[SP] - stack[SP + 1];
                        break;
                    // MUL - Pop twice -> multiply -> push
                    case 4:
                        SP--;
                        stack[SP] = stack[SP] * stack[SP + 1];
                        break;
                    // DIV - Pop twice -> divide top value from bottom value -> push
                    case 5:
                        SP--;
                        stack[SP] = stack[SP] / stack[SP + 1];
                        break;
                    // ODD - Pop once -> push 1 if odd and 0 if even
                    case 6:
                        stack[SP] = stack[SP] % 2;
                        break;
                    // MOD - Pop twice -> mod top value from bottom value -> push
                    case 7:
                        SP--;
                        stack[SP] = stack[SP] % stack[SP + 1];
                        break;
                    // EQL - Pop twice -> push 1 if first = second, 0 otherwise
                    case 8:
                        SP--;
                        stack[SP] = stack[SP] == stack[SP + 1];
                    // NEQ - Pop twice -> push 1 if first does not equal second, 0 otherwise
                    case 9:
                        SP--;
                        stack[SP] = stack[SP] != stack[SP + 1];
                        break;
                    // LSS - Pop twice -> push 1 if second < first, 0 otherwise
                    case 10:
                        SP--;
                        stack[SP] = stack[SP] < stack[SP + 1];
                        break;
                    // LEQ - Pop twice -> push 1 if second <= first, 0 otherwise
                    case 11:
                        SP--;
                        stack[SP] = stack[SP] <= stack[SP + 1];
                        break;
                    // GTR - Pop twice -> push 1 if second > first, 0 otherwise
                    case 12:
                        SP--;
                        stack[SP] = stack[SP] > stack[SP + 1];
                    // GEQ - Pop twice -> push 1 if second >= first, 0 otherwise
                    case 13:
                        SP--;
                        stack[SP] = stack[SP] >= stack[SP + 1];
                }
                break;
            // LOD - Read the value at offset M, L levels down, and push onto stack
            case 3:
                SP++;
                stack[SP] = stack[base(L, BP, stack) + M];
                PC++;
                break;
            // STO - Pop the stack and write value into offset M, L levels down
            case 4:
                stack[base(L, BP, stack) + M] = stack[SP];
                stack[SP] = 0;
                SP--;
                PC++;
                break;
            // CAL - Call the procedure at M
            case 5:
                stack[SP + 1] = 0;
                stack[SP + 2] = base(L, BP, stack);
                stack[SP + 3] = BP;
                stack[SP + 4] = PC + 1;
                BP = SP + 1;
                PC = M;
                break;
            // INC - Allocate space for M local variables, will always allocate atleast 4
            case 6:
                SP = SP + M;
                PC++;
                break;
            // JMP - Branch to M
            case 7:
                PC = M;
                break;
            // JPC - Pop the stack and branch to M if result is 0
            case 8:
                if(stack[SP] == 0)
                    PC = M;
                else
                    PC++;
                SP--;
                break;
            // SIO 1 - Pop the stack and write result to screen
            case 9:
                printf("%d\n", stack[SP]);
                SP--;
                PC++;
                break;
            // SIO 2 - Take user input and push on the stack
            case 10:
                printf("Enter Value:\n");
                SP++;
                scanf("%d", &stack[SP]);
                PC++;
                break;
            // SIO 3 - Terminate
            case 11:
                printf("Halt\n");
                halt = true;
                BP = 0;
                PC = 0;
                SP = 0;
                break;
            default:
                printf("Invalid Opcode\n");
                return 0;
        }

        // Print the stacktrace for the instructions that were just executed
        printStacktrace(ofp, prev, IR, PC, BP, SP, stack);
    }

    // Close
    fclose(ofp);

    return 0;
}