: '

: '

̲Ͳ ²

ֲ Ͳ ² ˲Ͳ

"Ͳ Ͳ "

:

:

. . ʲ-34

ҳ . .

:

. .

. .

2010


" " .1". 䳿 CISC - . .

:

ü  -, .

ü  .

ü  .

, -, .


' '

˳


CISC - . , :

1.  .

2.  .

3.  г , .

4.  - .

5.  .

6.  .

7.  .

8.  , . , . , .

9.  .

10.  , , .

:

-  , ;

-  ;

-  ;

-  ;

-  .

' :

1.  '.

2.  , .

3.  , .

4.  ( ' ).

5.  .

6.  , ' .

7.  ' .

8.  ϳ , .

'

:

-  , ' - ;

-  , ' ;

-  , ' ;

-  ;

-  , ', , ;

-  -' '-'.

- - , ' , , ' . ', , - , : , , , , , .

() ' . :

-  ();

-  ();

-  ()

-  ().

'. '. , . '. . ' .

' , , , . . : (), ' (N), (Z), (), (V), .. ' , . '. , . , . (), - . () . . .


г , , 䳿 - .

, .

:

-  ,

-  ,

-  .

- , , , , . :

-  , ( - );

-  (1);

-  (2);

-  (3).

- . , .

' . , , , , . ³ , .

k . N = 2k . ʳ , , , ' . ' Nc , k : k = [log Nc], .

( ) m . . mi , - (=1,2,. n), n - . ' 2n .

k + m , , '. , 8, 16, 32 .

: , , (). . 3 () 1 , 4 () - 1 . :

(000011111111) 2= (0377) 8= (0FF) 16;

, . - 3- 4- , . :

ADD - (add),

SUB - (subtract),

MPY - (multiply),

DIV - (divide).

. ADD R Y ' Y R. , , ' .

, ' . , . , .

, , . , , . ֳ , ', ' .

 

() . , , ' ' . ' , , : ; ; ; . . .

- . , .

- , .

- . . г - , .

³ - , : , , , . г . , ( 1). - : , .

- . , ( 䳿 - ). . . , . , .

9
1 2 3 4 5 6 7 8 1 2 3
9 3 5 9 1 2 17 2 10 ZF 2 3 5 1

1.  . 8 . 3 , 3 2 . .

: A

1

ADD 00000 regA regB, destReg R
2 DIV 01000 destReg=regA/regB R
3 IMUL 01001 destReg=regA*regB R
4 XIDIV 01010 destReg=regA/regB R

: 5

AND 01011 : destReg=regA & regB R
6 NAND 00001

- regA regB,

destReg

R
7 XOR 01100 2: destReg=regA # regB R
8 CMPGE 01101 regA regB destReg= regA >= regB R

R-:

24-22:

21-19: reg A

18-16: reg B

15-3: (=0)

2-0: destReg

9

LW 00010

regB .

regA.

I

: 10

SW 00011

regB .

regA.

I
11 BEQ 00100

regA regB ,

() + 1+, beq .

I
12 JMAE 01110 / if (regA>= regB) PC=PC+1+offSet I
13 JMNAE 01111 / if (regA! >= regB) PC=PC+1+offSet I
14 JNE 10010

, , if (ZF!

=0) PC=offset

I

I- :

24-22:

21-19: reg A

18-16: reg B

15-0: (16 , - 32768 32767)

offset

 

15 JARL 00101

+1 regB, (jalr)

. , regA. regA regB , +1, +1.

J
16 BSF 10000 ( ) regA 1, destReg. 1 ZF=1, ZF=0 J
17 BSR 10001

( ) regA 1, destReg. 1

ZF=1, ZF=0

J

J- :

24-22:

21-19: reg A

18-16: reg B

15-0: (=0)

unused

 

- ( ). : PUSH, POP.

18 HALT 00110

1, ,

, .

O
19 NOOP 00111 ͳ O
20 PUSH 10011 1 O
21 POP 10100 1 O

O- :

24-22:

21-0: (=0)

unused

 
\

' '

:

1.

13 , 2 5 ( 32 21). . 32 32 , , ZF.


1. div: 45/5=9.


:

lw 0 1 num1

lw 0 2 num2

div 1 2 3

done halt

num1 .fill 45

num2 .fill 5

:

8454148

8519685

34209795

25165824

45

5


ʳ :

@@@

state:

pc 4

ZF = 0

stack:

memory:

mem[ 0 ] 8454148

mem[ 1 ] 8519685

mem[ 2 ] 34209795

mem[ 3 ] 25165824

mem[ 4 ] 45

mem[ 5 ] 5

registers:

reg[ 0 ] 0

reg[ 1 ] 45

reg[ 2 ] 5

reg[ 3 ] 9

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

2. imul: 3*(-4)=-12.


:

lw 0 1 num1

lw 0 2 num2

imul 1 2 3

done halt

num1 .fill 3

num2 .fill -4

:

8454148

8519685

34209795

25165824

3

-4


ʳ :

@@@

state:

pc 4

ZF = 0

stack:

memory:

mem[ 0 ] 8454148

mem[ 1 ] 8519685

mem[ 2 ] 38404099

mem[ 3 ] 25165824

mem[ 4 ] 3

mem[ 5 ] -4

registers:

reg[ 0 ] 0

reg[ 1 ] 3

reg[ 2 ] -4

reg[ 3 ] -12

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

3. xidiv: 30/(-5)=-6, .


:

lw 0 1 num1

lw 0 2 num2

xidiv 1 2 3

done halt

num1 .fill 30

num2 .fill -5

:

8454148

8519685

42598403

25165824

30

-5


ʳ :

@@@

state:

pc 4

ZF = 0

stack:

memory:

mem[ 0 ] 8454148

mem[ 1 ] 8519685

mem[ 2 ] 42598403

mem[ 3 ] 25165824

mem[ 4 ] 30

mem[ 5 ] -5

registers:

reg[ 0 ] 0

reg[ 1 ] -5

reg[ 2 ] 30

reg[ 3 ] -6

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

4.and: 5&3=1

0101

&

0011

0001


:

lw 0 1 num1

lw 0 2 num2

andf 1 2 3

done halt

num1 .fill 5

num2 .fill 3

:

8454148

8519685

46792707

25165824

5

3


ʳ :

@@@

@@@

state:

pc 4

ZF = 0

stack:

memory:

mem[ 0 ] 8454148

mem[ 1 ] 8519685

mem[ 2 ] 46792707

mem[ 3 ] 25165824

mem[ 4 ] 5

mem[ 5 ] 3

registers:

reg[ 0 ] 0

reg[ 1 ] 5

reg[ 2 ] 3

reg[ 3 ] 1

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

xor: 5#3=6

0101

#

0011

0110


:

lw 0 1 num1

lw 0 2 num2

xorf 1 2 3

done halt

num1 .fill 3

num2 .fill 5

:

8454148

8519685

50987011

25165824

3

5


ʳ :

@@@

state:

pc 4

ZF = 0

stack:

memory:

mem[ 0 ] 8454148

mem[ 1 ] 8519685

mem[ 2 ] 50987011

mem[ 3 ] 25165824

mem[ 4 ] 3

mem[ 5 ] 5

registers:

reg[ 0 ] 0

reg[ 1 ] 3

reg[ 2 ] 5

reg[ 3 ] 6

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

6. cmpge: 1= 5>=3


:

@@@

state:

pc 4

ZF = 0

stack:

memory:

mem[ 0 ] 8454148

mem[ 1 ] 8519685

mem[ 2 ] 55181315

mem[ 3 ] 25165824

mem[ 4 ] 5

mem[ 5 ] 3

registers:

reg[ 0 ] 0

reg[ 1 ] 5

reg[ 2 ] 3

reg[ 3 ] 1

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

7. jma: if (7>=4) reg[4]=7; else reg[5]=4, reg[4]=7.


:

lw 0 1 num1

lw 0 2 num2

jmae 1 2 1

lw 0 5 num2

lw 0 4 num1

done halt

num1 .fill 7

num2 .fill 4

:

8454150

8519687

59375617

8716295

8650758

25165824

7

3


ʳ :

@@@

state:

pc 6

ZF = 0

stack:

memory:

mem[ 0 ] 8454150

mem[ 1 ] 8519687

mem[ 2 ] 59375617

mem[ 3 ] 8716295

mem[ 4 ] 8650758

mem[ 5 ] 25165824

mem[ 6 ] 7

mem[ 7 ] 4

registers:

reg[ 0 ] 0

reg[ 1 ] 7

reg[ 2 ] 4

reg[ 3 ] 0

reg[ 4 ] 7

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

8. jmnae: if (5!>=6) reg[4]=6; else reg[4]=5, reg[5]=6.


:

lw 0 1 num1

lw 0 2 num2

jmnae 1 2 1

lw 0 5 num2

lw 0 4 num1

done halt

num1 .fill 5

num2 .fill 6

:

8454150

8519687

63569921

8716295

8650758

25165824

5

6


ʳ :

@@@

state

pc 6

ZF = 0

stack:

memory:

mem[ 0 ] 8454150

mem[ 1 ] 8519687

mem[ 2 ] 63569921

mem[ 3 ] 8716295

mem[ 4 ] 8650758

mem[ 5 ] 25165824

mem[ 6 ] 5

mem[ 7 ] 6

registers:

reg[ 0 ] 0

reg[ 1 ] 5

reg[ 2 ] 6

reg[ 3 ] 0

reg[ 4 ] 5

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

9. bsr: if (16=1000) 1 4.


:

lw 0 1 num1

bsr 1 2

done halt

num1 .fill 16

:

8454150

8519687

25165824

16


ʳ :

@@@

state:

pc 3

ZF = 1

stack:

memory:

mem[ 0 ] 8454147

mem[ 1 ] 71958528

mem[ 2 ] 25165824

mem[ 3 ] 16

registers:

reg[ 0 ] 0

reg[ 1 ] -2147483648

reg[ 2 ] 4

reg[ 3 ] 0

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

10. bsf: 8 (1000) 1 3.


:

lw 0 1 num1

bsf 1 2

done halt

num1 .fill 8

:

8454147

71958528

25165824

8


ʳ :

@@@

@@@

state:

pc 3

ZF = 1

stack:

memory:

mem[ 0 ] 8454147

mem[ 1 ] 67764224

mem[ 2 ] 25165824

mem[ 3 ] 8

registers:

reg[ 0 ] 0

reg[ 1 ] 1

reg[ 2 ] 3

reg[ 3 ] 0

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

11. jne: if (16=1000) 1 4, ZF=1: , else reg[4]=8.


:

lw 0 1 num1

bsr 1 0 3

jne 0 0 4

lw 0 4 num1

done halt

num1 .fill 8

:

8454150

8519687

67764224

8454147

25165824

8


ʳ :

@@@

state:

@@@

state:

pc 5

ZF = 1

stack:

memory:

mem[ 0 ] 8454149

mem[ 1 ] 71827456

mem[ 2 ] 75497476

mem[ 3 ] 8650757

mem[ 4 ] 25165824

mem[ 5 ] 8

registers:

reg[ 0 ] 0

reg[ 1 ] -2147483648

reg[ 2 ] 0

reg[ 3 ] 0

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

12. push, pop: push 2, push 3, pop, pop.


:

lw 0 1 num1

push

lw 0 1 num2

push

pop

pop

done halt

num1 .fill 2

num2 .fill 3

:

8454150

79691776

8454151

79691776

83886080

83886080

25165824

2

3


, push:

@@@

state:

pc 4

ZF = 0

stack:

stk[ 0 ] 2

stk[ 1 ] 3

memory:

mem[ 0 ] 8454151

mem[ 1 ] 79691776

mem[ 2 ] 8454152

mem[ 3 ] 79691776

mem[ 4 ] 83886080

mem[ 5 ] 83886080

mem[ 6 ] 25165824

mem[ 7 ] 2

mem[ 8 ] 3

registers:

reg[ 0 ] 0

reg[ 1 ] 3

reg[ 2 ] 0

reg[ 3 ] 0

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state

ʳ :

@@@

state:

pc 7

ZF = 0

stack:

memory:

mem[ 0 ] 8454151

mem[ 1 ] 79691776

mem[ 2 ] 8454152

mem[ 3 ] 79691776

mem[ 4 ] 83886080

mem[ 5 ] 83886080

mem[ 6 ] 25165824

mem[ 7 ] 2

mem[ 8 ] 3

registers:

reg[ 0 ] 0

reg[ 1 ] 2

reg[ 2 ] 0

reg[ 3 ] 0

reg[ 4 ] 0

reg[ 5 ] 0

reg[ 6 ] 0

reg[ 7 ] 0

end state


CISC - . . 䳿 CISC - . CISC - , , , . CISC - , . .


˳

1.  .. . . - : , 2008. - 470 .

2.  .. . - .: -, 2006. - 320 .

3.  . .5- . (+CD). - .: , 2007. - 844 .

4.  Patterson D., and Hennessy J.computer Architecture. A quantitative Approach. Second Edition. - Morgan Kaufmann Publishers, Inc., San Francisco, California, 1996. - 760 p.


I ( -):

/* Assembler for LC */

#include <stdlib. h>

#include <stdio. h>

#include <string. h>

#define MAXLINELENGTH 1000

#define MAXNUMLABELS 65536

#define MAXLABELLENGTH 7 /* includes the null character termination */

#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

int readandfParse (FILE *, char *, char *, char *, char *, char *);

int translateSymbol (char labelArray [MAXNUMLABELS] [MAXLABELLENGTH], int labelAddress [MAXNUMLABELS], int, char *);

int isNumber (char *);

void testRegArg (char *);

void testAddrArg (char *);

int main (int argc, char *argv [])

{

char *inFileString, *outFileString;

FILE *inFilePtr, *outFilePtr;

int address;

char label [MAXLINELENGTH], opcode [MAXLINELENGTH], arg0 [MAXLINELENGTH],

arg1 [MAXLINELENGTH], arg2 [MAXLINELENGTH], argTmp [MAXLINELENGTH];

int i;

int numLabels=0;

int num;

int addressField;

char labelArray [MAXNUMLABELS] [MAXLABELLENGTH];

int labelAddress [MAXNUMLABELS];

if (argc! = 3) {

printf ("error: usage: %s <assembly-code-file> <machine-code-file>\n",

argv [0]);

exit (1);

}

inFileString = argv [1];

outFileString = argv [2];

inFilePtr = fopen (inFileString, "r");

if (inFilePtr == NULL) {

printf ("error in opening %s\n", inFileString);

exit (1);

}

outFilePtr = fopen (outFileString, "w");

if (outFilePtr == NULL) {

printf ("error in opening %s\n", outFileString);

exit (1);

}

/* map symbols to addresses */

/* assume address start at 0 */

for (address=0; readandfParse (inFilePtr, label, opcode, arg0, arg1, arg2);

address++) {

/*

printf ("%d: label=%s, opcode=%s, arg0=%s, arg1=%s, arg2=%s\n",

address, label, opcode, arg0, arg1, arg2);

*/

/* check for illegal opcode */

if (strcmp (opcode, "add") && strcmp (opcode, "nand") &&

strcmp (opcode, "lw") && strcmp (opcode, "sw") &&

strcmp (opcode, "beq") && strcmp (opcode, "jalr") &&

strcmp (opcode, "halt") && strcmp (opcode, "noop") &&

strcmp (opcode,". fill") && strcmp (opcode, "div") &&

strcmp (opcode, "imul") && strcmp (opcode, "xidiv") &&

strcmp (opcode, "andf") && strcmp (opcode, "xorf") &&

strcmp (opcode, "cmpge") && strcmp (opcode, "jmae") &&

strcmp (opcode, "jmnae") && strcmp (opcode, "bsr") &&

strcmp (opcode, "jne") && strcmp (opcode, "bsf") &&

strcmp (opcode, "push") && strcmp (opcode, "pop"))

{

printf ("error: unrecognized opcode %s at address %d\n", opcode,

address);

exit (1);

}

/* check register fields */

if (! strcmp (opcode, "add") ||! strcmp (opcode, "nand") ||

! strcmp (opcode, "lw") ||! strcmp (opcode, "sw") ||

! strcmp (opcode, "beq") ||! strcmp (opcode, "jalr") ||

! strcmp (opcode, "div") ||! strcmp (opcode, "imul") ||

! strcmp (opcode, "xidiv") ||! strcmp (opcode, "andf") ||

! strcmp (opcode, "xorf") ||! strcmp (opcode, "cmpge") ||

! strcmp (opcode, "bsf") ||! strcmp (opcode, "bsr"))

{

testRegArg (arg0);

testRegArg (arg1);

}

if (! strcmp (opcode, "nand") ||! strcmp (opcode, "add") ||

! strcmp (opcode, "div") ||! strcmp (opcode, "imul") ||

! strcmp (opcode, "xidiv") ||! strcmp (opcode, "andf") ||

! strcmp (opcode, "xorf") ||! strcmp (opcode, "cmpge"))

{

testRegArg (arg2);

}

/* check addressField */

if (! strcmp (opcode, "lw") ||! strcmp (opcode, "sw") ||

! strcmp (opcode, "beq") ||! strcmp (opcode, "jmae") ||

! strcmp (opcode, "jmnae") ||! strcmp (opcode, "jne"))

{

testAddrArg (arg2);

}

if (! strcmp (opcode,". fill"))

{

testAddrArg (arg0);

}

/* check for enough arguments */

if ( (strcmp (opcode, "halt") && strcmp (opcode, "noop") &&

strcmp (opcode,". fill") && strcmp (opcode, "jalr") &&

strcmp (opcode, "bsf") && strcmp (opcode, "bsr") &&

strcmp (opcode, "pop") && strcmp (opcode, "push") &&

strcmp (opcode, "je") && arg2 [0] =='\0') ||

(! strcmp (opcode, "jalr") && arg1 [0] =='\0') ||

(! strcmp (opcode,". fill") && arg0 [0] =='\0'))

{

printf ("error at address %d: not enough arguments\n", address);

exit (2);

}

if (label [0]! = '\0') {

/* check for labels that are too long */

if (strlen (label) >= MAXLABELLENGTH) {

printf ("label too long\n");

exit (2);

}

/* make sure label starts with letter */

if (! sscanf (label, "% [a-zA-Z]", argTmp)) {

printf ("label doesn't start with letter\n");

exit (2);

}

/* make sure label consists of only letters andf numbers */

sscanf (label, "% [a-zA-Z0-9]", argTmp);

if (strcmp (argTmp, label)) {

printf ("label has character other than letters andf numbers\n");

exit (2);

}

/* look for duplicate label */

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

if (! strcmp (label, labelArray [i])) {

printf ("error: duplicate label %s at address %d\n",

label, address);

exit (1);

}

}

/* see if there are too many labels */

if (numLabels >= MAXNUMLABELS) {

printf ("error: too many labels (label=%s) \n", label);

exit (2);

}

strcpy (labelArray [numLabels], label);

labelAddress [numLabels++] = address;

}

}

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

/* printf ("%s = %d\n", labelArray [i], labelAddress [i]); */

}

/* now do second pass (print machine code, with symbols filled in as

addresses) */

rewind (inFilePtr);

for (address=0; readandfParse (inFilePtr, label, opcode, arg0, arg1, arg2);

address++) {

if (! strcmp (opcode, "add"))

num = (ADD << else if (! strcmp (opcode, "nand"))

else if (! strcmp (opcode, "div"))

num = (div << else if (! strcmp (opcode, "imul")) (atoi (arg1) << 16) else if (! strcmp (opcode, "xidiv"))

else if (! strcmp (opcode, "andf")) else if (! strcmp (opcode, "xorf")) else if (! strcmp (opcode, "cmpge"))

else if (! strcmp (opcode, "jalr")) (atoi (arg1) << 16);

else if (! strcmp (opcode, "bsf")) else if (! strcmp (opcode, "push")) {

num = (push << 22);

} else if (! strcmp (opcode, "pop")) {

num = (pop << 22);

} else if (! strcmp (opcode, "halt")) {

num = (HALT << 22);

} else if (! strcmp (opcode, "noop")) {

num = (NOOP << 22);

} else if (! strcmp (opcode, "bsr"))

else if (! strcmp (opcode, "lw") ||! strcmp (opcode, "sw") ||

! strcmp (opcode, "beq") ||! strcmp (opcode, "jmae") ||

! strcmp (opcode, "jmnae") ||! strcmp (opcode, "jne")) {

/* if arg2 is symbolic, then translate into an address */

if (! isNumber (arg2)) {

addressField = translateSymbol (labelArray, labelAddress,

numLabels, arg2);

/*

printf ("%s being translated into %d\n", arg2, addressField);

*/

if (! strcmp (opcode, "beq") ||! strcmp (opcode, "jmae") ||! strcmp (opcode, "jmnae")) {

addressField = addressField-address-1;

}

} else {

addressField = atoi (arg2);

}

if (addressField < - 32768 || addressField > 32767) {

printf ("error: offset %d out of range\n", addressField);

exit (1);

}

/* truncate the offset field, in case it's negative */

addressField = addressField & 0xFFFF;

if (! strcmp (opcode, "beq")) addressField;

else if (! strcmp (opcode, "jmae"))

else if (! strcmp (opcode, "jmnae"))

num = (jmnae << else if (! strcmp (opcode, "jne"))

else {

/* lw or sw */

if (! strcmp (opcode, "lw"))

(atoi (arg1) << else

}

} 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) \n", address, num, num); */

fprintf (outFilePtr, "%d\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] = '\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\n");

exit (1);

}

/* is there a label? */

ptr = line;

if (sscanf (ptr, "% [^\t\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, "%* [\t\n\r] % [^\t\n\r] %* [\t\n\r] % [^\t\n\r] %* [\t\n\r] % [^\t\n\r] %* [\t\n\r] % [^\t\n\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\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);

}


 
2011 , .