p align="left">printf ("error: missing label %s\n", symbol); exit (1); } return (labelAddress [i]); } int isNumber (char *string) { /* return 1 if string is a number */ int i; return ( (sscanf (string, "%d", &i)) == 1); } /* Test register argument; make sure it's in range andf has no bad characters. */ void testRegArg (char *arg) { int num; char c; if (atoi (arg) < 0 || atoi (arg) > 7) { printf ("error: register out of range\n"); exit (2); } if (sscanf (arg, "%d%c", &num, &c)! = 1) { printf ("bad character in register argument\n"); exit (2); } } /* Test addressField argument. */ void testAddrArg (char *arg) { int num; char c; /* test numeric addressField */ if (isNumber (arg)) { if (sscanf (arg, "%d%c", &num, &c)! = 1) { printf ("bad character in addressField\n"); exit (2); } } }Додаток II (код симулятора) /*Instruction-level simulator for the LC */ #include <stdio. h> #include <stdlib. h> #include <string> #include <math. h> #include <vector> using namespace std; #define NUMMEMORY 65536 /* maximum number of words in memory */ #define NUMREGS 8 /* number of machine registers */ #define MAXLINELENGTH 1000 #define STACKDEPTH 32 #define ADD 0 #define NAND 1 #define LW 2 #define SW 3 #define BEQ 4 #define JALR 5 #define HALT 6 #define NOOP 7 #define div 8 #define imul 9 #define xidiv 10 #define andf 11 #define xorf 12 #define cmpge 13 #define jmae 14 #define jmnae 15 #define bsf 16 #define bsr 17 #define jne 18 #define push 19 #define pop 20 typedef struct stateStruct { int pc; int mem [NUMMEMORY]; int reg [NUMREGS]; int numMemory; vector <int> sStack; int ZF; } stateType; void printState (stateType *); void run (stateType); int convertNum (int); int main (int argc, char *argv []) { int i; char line [MAXLINELENGTH]; stateType state; FILE *filePtr; if (argc! = 2) { printf ("error: usage: %s <machine-code file>\n", argv [0]); exit (1); } /* initialize memories and registers */ for (i=0; i<NUMMEMORY; i++) { state. mem [i] = 0; } for (i=0; i<NUMREGS; i++) { state. reg [i] = 0; } state. ZF=0; state. pc=0; /* read machine-code file into instruction/data memory (starting at address 0) */ filePtr = fopen (argv [1], "r"); if (filePtr == NULL) { printf ("error: can't open file %s\n", argv [1]); perror ("fopen"); exit (1); } for (state. numMemory=0; fgets (line, MAXLINELENGTH, filePtr)! = NULL; state. numMemory++) { if (state. numMemory >= NUMMEMORY) { printf ("exceeded memory size\n"); exit (1); } if (sscanf (line, "%d", state. mem+state. numMemory)! = 1) { printf ("error in reading address %d\n", state. numMemory); exit (1); } printf ("memory [%d] =%d\n", state. numMemory, state. mem [state. numMemory]); } printf ("\n"); /* run never returns */ run (state); return (0); } void run (stateType state) { int i; int arg0, arg1, arg2, addressField; int instructions=0; int opcode; int maxMem=-1; /* highest memory address touched during run */ for (; 1; instructions++) { /* infinite loop, exits when it executes halt */ printState (&state); if (state. pc < 0 || state. pc >= NUMMEMORY) { printf ("pc went out of the memory range\n"); exit (1); } maxMem = (state. pc > maxMem)? state. pc: maxMem; /* this is to make the following code easier to read */ opcode = state. mem [state. pc] >> 22; arg0 = (state. mem [state. pc] >> 19) & 0x7; arg1 = (state. mem [state. pc] >> 16) & 0x7; arg2 = state. mem [state. pc] & 0x7; /* only for add, nand */ addressField = convertNum (state. mem [state. pc] & 0xFFFF); /* for beq, lw, sw */ state. pc++; if (opcode == ADD) { state. reg [arg2] = state. reg [arg0] + state. reg [arg1]; } else if (opcode == NAND) { state. reg [arg2] = ~ (state. reg [arg0] & state. reg [arg1]); } else if (opcode == LW) { if (state. reg [arg0] + addressField < 0 || state. reg [arg0] + addressField >= NUMMEMORY) { printf ("address out of bounds\n"); exit (1); } state. reg [arg1] = state. mem [state. reg [arg0] + addressField]; if (state. reg [arg0] + addressField > maxMem) { maxMem = state. reg [arg0] + addressField; } } else if (opcode == SW) { if (state. reg [arg0] + addressField < 0 || state. reg [arg0] + addressField >= NUMMEMORY) { printf ("address out of bounds\n"); exit (1); } state. mem [state. reg [arg0] + addressField] = state. reg [arg1]; if (state. reg [arg0] + addressField > maxMem) { maxMem = state. reg [arg0] + addressField; } } else if (opcode == BEQ) { if (state. reg [arg0] == state. reg [arg1]) { state. pc += addressField; } } else if (opcode == JALR) { state. reg [arg1] = state. pc; if (arg0! = 0) state. pc = state. reg [arg0]; else state. pc = 0; } else if (opcode == NOOP) { } else if (opcode == HALT) { printf ("machine halted\n"); printf ("total of %d instructions executed\n", instructions+1); printf ("final state of machine: \n"); printState (&state); exit (0); } else if (opcode == xidiv) { state. reg [arg2] = state. reg [arg0] / state. reg [arg1]; state. reg [arg0] ^=state. reg [arg1] ^=state. reg [arg0] ^=state. reg [arg1]; } else if (opcode == div) { state. reg [arg2] = (unsigned) state. reg [arg0] / (unsigned) state. reg [arg1]; } else if (opcode == imul) { state. reg [arg2] = state. reg [arg0] * state. reg [arg1]; } else if (opcode == andf) { state. reg [arg2] = state. reg [arg0] & state. reg [arg1]; } else if (opcode == xorf) { state. reg [arg2] = state. reg [arg0] xor state. reg [arg1]; } else if (opcode == cmpge) { state. reg [arg2] = state. reg [arg0] >= state. reg [arg1]; } else if (opcode == jmae) { if ( (unsigned) state. reg [arg0] >= (unsigned) state. reg [arg1]) state. pc += addressField; } else if (opcode == jmnae) { if ( (unsigned) state. reg [arg0] < (unsigned) state. reg [arg1]) state. pc += addressField; } else if (opcode == bsf) { state. ZF=0; for (i=0; i<31; i++) { if (state. reg [arg0] %2==1) { state. ZF=1; state. reg [arg1] =i; break; } else { state. reg [arg0] =state. reg [arg0] >>1; } } } else if (opcode == bsr) { state. ZF=0; for (i=31; i>0; i--) { if (state. reg [arg0] /0x80000000==1) { state. ZF=1; state. reg [arg1] =i; break; } else { state. reg [arg0] =state. reg [arg0] <<1; } } } else if (opcode == jne) { if (state. ZF! =0) state. pc = addressField; } else if (opcode == push) { if (state. sStack. size () > STACKDEPTH - 1) { printf ("\nerror: stack overflow! 0x%x\n", opcode); printf ("total of %d instructions executed\n", instructions+1); printf ("final state of machine: \n"); printState (&state); exit (1); } else state. sStack. push_back (state. reg [1]); } else if (opcode == pop) { if (state. sStack. empty ()) { printf ("\nerror: stack underflow! 0x%x\n", opcode); printf ("total of %d instructions executed\n", instructions+1); printf ("final state of machine: \n"); printState (&state); exit (1); } else { state. reg [1] = state. sStack. back (); state. sStack. pop_back (); } } else { printf ("error: illegal opcode 0x%x\n", opcode); exit (1); } state. reg [0] = 0; } } void printState (stateType *statePtr) { int i; printf ("\n@@@\nstate: \n"); printf ("\tpc %d\n", statePtr->pc); printf ("\t\tZF = %d\n",statePtr->ZF); vector <int>:: iterator stackiter; printf ("\tstack: \n"); for (stackiter = statePtr->sStack. begin (), i = 0; stackiter < statePtr->sStack. end (); stackiter++, i++) { printf ("\t\tstek [%d] %d\n", i, *stackiter); } printf ("\tmemory: \n"); for (i=0; i<statePtr->numMemory; i++) { printf ("\t\tmem [%d] %d\n", i, statePtr->mem [i]); } printf ("\tregisters: \n"); for (i=0; i<NUMREGS; i++) { printf ("\t\treg [%d] %d\n", i, statePtr->reg [i]); } printf ("end state\n"); } int convertNum (int num) { /* convert a 16-bit number into a 32-bit Sun integer */ if (num & (1<<15)) { num - = (1<<16); } return (num); }
Страницы: 1, 2, 3, 4, 5
|