Смекни!
smekni.com

Проектування комп`ютера (стр. 5 из 5)

num = (LW << 22) | (atoi (arg0) << 19) |

(atoi (arg1) << 16) | addressField;

} else {

num = (SW << 22) | (atoi (arg0) << 19) |

(atoi (arg1) << 16) | addressField;

}

}

} else if (! strcmp (opcode,". fill")) {

if (! isNumber (arg0)) {

num = translateSymbol (labelArray, labelAddress, numLabels,

arg0);

} else {

num = atoi (arg0);

}

}

/* printf (" (address %d): %d (hex 0x%x) &bsol;n", address, num, num); */

fprintf (outFilePtr, "%d&bsol;n", num);

}

exit (0);

}

/*

* Read andf parse a line of the assembly-language file. Fields are returned

* in label, opcode, arg0, arg1, arg2 (these strings must have memory already

* allocated to them).

*

* Return values:

* 0 if reached end of file

* 1 if all went well

*

* exit (1) if line is too long.

*/

int readandfParse (FILE *inFilePtr, char *label, char *opcode, char *arg0,char *arg1, char *arg2)

{

char line [MAXLINELENGTH];

char *ptr = line;

/* delete prior values */

label [0] = opcode [0] = arg0 [0] = arg1 [0] = arg2 [0] = '&bsol;0';

/* read the line from the assembly-language file */

if (fgets (line, MAXLINELENGTH, inFilePtr) == NULL) {

/* reached end of file */

return (0);

}

/* check for line too long */

if (strlen (line) == MAXLINELENGTH-1) {

printf ("error: line too long&bsol;n");

exit (1);

}

/* is there a label? */

ptr = line;

if (sscanf (ptr, "% [^&bsol;t&bsol;n]", label)) {

/* successfully read label; advance pointer over the label */

ptr += strlen (label);

}

/*

* Parse the rest of the line. Would be nice to have real regular

* expressions, but scanf will suffice.

*/

sscanf (ptr, "%* [&bsol;t&bsol;n&bsol;r] % [^&bsol;t&bsol;n&bsol;r] %* [&bsol;t&bsol;n&bsol;r] % [^&bsol;t&bsol;n&bsol;r] %* [&bsol;t&bsol;n&bsol;r] % [^&bsol;t&bsol;n&bsol;r] %* [&bsol;t&bsol;n&bsol;r] % [^&bsol;t&bsol;n&bsol;r] ",

opcode, arg0, arg1, arg2);

return (1);

}

int translateSymbol (char labelArray [MAXNUMLABELS] [MAXLABELLENGTH],

int labelAddress [MAXNUMLABELS], int numLabels, char *symbol)

{

int i;

/* search through address label table */

for (i=0; i<numLabels && strcmp (symbol, labelArray [i]); i++) {

}

if (i>=numLabels) {

printf ("error: missing label %s&bsol;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&bsol;n");

exit (2);

}

if (sscanf (arg, "%d%c", &num, &c)! = 1) {

printf ("bad character in register argument&bsol;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&bsol;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>&bsol;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&bsol;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&bsol;n");

exit (1);

}

if (sscanf (line, "%d", state. mem+state. numMemory)! = 1) {

printf ("error in reading address %d&bsol;n", state. numMemory);

exit (1);

}

printf ("memory [%d] =%d&bsol;n", state. numMemory, state. mem [state. numMemory]);

}

printf ("&bsol;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&bsol;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&bsol;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&bsol;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&bsol;n");

printf ("total of %d instructions executed&bsol;n", instructions+1);

printf ("final state of machine: &bsol;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 ("&bsol;nerror: stack overflow! 0x%x&bsol;n", opcode);

printf ("total of %d instructions executed&bsol;n", instructions+1);

printf ("final state of machine: &bsol;n");

printState (&state);

exit (1);

}

else state. sStack. push_back (state. reg [1]);

} else if (opcode == pop) {

if (state. sStack. empty ())

{

printf ("&bsol;nerror: stack underflow! 0x%x&bsol;n", opcode);

printf ("total of %d instructions executed&bsol;n", instructions+1);

printf ("final state of machine: &bsol;n");

printState (&state);

exit (1);

}

else

{

state. reg [1] = state. sStack. back ();

state. sStack. pop_back ();

}

} else {

printf ("error: illegal opcode 0x%x&bsol;n", opcode);

exit (1);

}

state. reg [0] = 0;

}

}

void

printState (stateType *statePtr)

{

int i;

printf ("&bsol;n@@@&bsol;nstate: &bsol;n");

printf ("&bsol;tpc %d&bsol;n", statePtr->pc);

printf ("&bsol;t&bsol;tZF = %d&bsol;n",statePtr->ZF);

vector <int>:: iterator stackiter;

printf ("&bsol;tstack: &bsol;n");

for (stackiter = statePtr->sStack. begin (), i = 0; stackiter < statePtr->sStack. end (); stackiter++, i++) {

printf ("&bsol;t&bsol;tstek [%d] %d&bsol;n", i, *stackiter);

}

printf ("&bsol;tmemory: &bsol;n");

for (i=0; i<statePtr->numMemory; i++) {

printf ("&bsol;t&bsol;tmem [%d] %d&bsol;n", i, statePtr->mem [i]);

}

printf ("&bsol;tregisters: &bsol;n");

for (i=0; i<NUMREGS; i++) {

printf ("&bsol;t&bsol;treg [%d] %d&bsol;n", i, statePtr->reg [i]);

}

printf ("end state&bsol;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);

}