Курсовая работа: Проектування комп'ютера
#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);
}
|