Issue with program acting as a behavioral simulator using machine code input. Getting incorrect output for the lw command

38 Views Asked by At

I wrote this C program that takes machine code as input and displays the memory and registers for each state. I used an assembler given to me by my professor to convert assembly code into machine code. The simulator reads the ints given and reads it like a 32bit binary instruction. My problem is the sample assembly code test works but when I try and do something simple like load 2 words and add them the output is wrong.

        lw      0   1   five    load reg1 with 5 (uses symbolic address)
        lw      1   2   3       load reg2 with -1 (uses numeric address)
start   add     1   2   1       decrement reg1
        beq     0   1   2       goto end of program when reg1==0
        beq     0   0   start   go back to the beginning of the loop
        noop    
done    halt                    end of program
five    .fill   5       
neg1    .fill   -1      
stAddr  .fill                   start will contain the address of start (2)

The above code works perfectly as intended the output is below

total of 17 instructions executed
final state of machine:

@@@
state:
        pc 8
        memory:
                mem[ 0 ] 8454151
                mem[ 1 ] 9043971
                mem[ 2 ] 655361
                mem[ 3 ] 16842754
                mem[ 4 ] 16842749
                mem[ 5 ] 29360128
                mem[ 6 ] 25165824
                mem[ 7 ] 5
                mem[ 8 ] -1
                mem[ 9 ] 2
        registers:
                reg[ 0 ] 0
                reg[ 1 ] 0
                reg[ 2 ] -1
                reg[ 3 ] 0
                reg[ 4 ] 0
                reg[ 5 ] 0
                reg[ 6 ] 0
                reg[ 7 ] 0
end state

When I try to run this assembly code The first lw works but the 2nd one doesn't

        lw      0   1   five    load reg1 with 5
        lw      1   2   one     load reg2 with 1
start   add     0   1   2       adds reg1 with reg2
done    halt                    end of program
five    .fill   5       
one    .fill    1      
stAddr  .fill                   start will contain the address of start (2)
@@@
state:
        pc 1
        memory:
                mem[ 0 ] 8454148
                mem[ 1 ] 9043973
                mem[ 2 ] 65538
                mem[ 3 ] 25165824
                mem[ 4 ] 5
                mem[ 5 ] 1
                mem[ 6 ] 2
        registers:
                reg[ 0 ] 0
                reg[ 1 ] 5
                reg[ 2 ] 0
                reg[ 3 ] 0
                reg[ 4 ] 0
                reg[ 5 ] 0
                reg[ 6 ] 0
                reg[ 7 ] 0
end state

@@@
state:
        pc 2
        memory:
                mem[ 0 ] 8454148
                mem[ 1 ] 9043973
                mem[ 2 ] 65538
                mem[ 3 ] 25165824
                mem[ 4 ] 5
                mem[ 5 ] 1
                mem[ 6 ] 2
        registers:
                reg[ 0 ] 0
                reg[ 1 ] 5
                reg[ 2 ] 0
                reg[ 3 ] 0
                reg[ 4 ] 0
                reg[ 5 ] 0
                reg[ 6 ] 0
                reg[ 7 ] 0
end state

And in case the simulator itself is wrong below is the function I used to simulate it

void simulate(stateType * state){
    int run = 0; 
    int count = 0;
    int opcode, arg0, arg1, arg2, offsetField;
    
    while (!run){
        printState(state);

        opcode = (state->mem[state->pc] & 29360128) >> 22;
        arg0 = (state->mem[state->pc] & 3670016) >> 19;
        arg1 = (state->mem[state->pc] & 458752) >> 16;
        arg2 = (state->mem[state->pc] & 7) >> 0;
        offsetField = convertNum(state->mem[state->pc] & 65535) >> 0;

        printf("%d\n",opcode);
        printf("%d\n",arg0);
        printf("%d\n",arg1);
        printf("%d\n",arg2);
        printf("%d\n",offsetField);
        
        switch(opcode) {
            case HALT:
                run = 1;
                ++state->pc;
            case ADD:
                state->reg[arg2] = state->reg[arg0] + state->reg[arg1];
                ++state->pc;
                break;
            case NAND:
                state->reg[arg2] = ~(state->reg[arg0] | state->reg[arg1]);
                ++state->pc;
                break;
            case LW:
                state->reg[arg1] = state->mem[state->reg[arg0] + offsetField];
                ++state->pc;
                break;
            case SW:
                state->mem[state->reg[arg0] + offsetField] = state->reg[arg1];
                ++state->pc;
                break;
            case BEQ:
                if (state->reg[arg0] == state->reg[arg1]){
                state->pc = state->pc + offsetField + 1;
                }
                else {
                    ++state->pc;
                }
                break;
            case JALR:
                state->reg[arg1] = state->pc + 1;
                state->pc  = state->reg[arg0];
                break;
            case NOOP:
                ++state->pc;
                break;
        }
    ++count;
    }
    
    
    printf("machine halted\n");
    printf("total of %d instructions executed\n", count);
    printf("final state of machine:\n");
    printState(state);
}

The machine code itself isn't the problem I have tested it and if asked I can provide the machine code. I've been stuck on this for awhile so any help whatsoever would be appreciated

0

There are 0 best solutions below