Project BRAIN Usually done in groups of two Each student responsible for implementing parts 1-4 with...

26

Transcript of Project BRAIN Usually done in groups of two Each student responsible for implementing parts 1-4 with...

Project BRAIN

Usually done in groups of two Each student responsible for implementing

parts 1-4 with their partner. Each team must demonstrate working version

of each part to TA and/or instructor. For each part of the project you must provide:

Commented, well-formatted source code for the BRAIN98 virtual machine

Commented source code for the BRAIN98 programs

You must provide a write-up for each part of the assignment.

This must describe the group’s efforts to address each step in the assignment and answer all questions asked in that part of the assignment, including any directions to discuss particular topics.

For some parts, you are also asked to include graphs, etc.

The documentation must be provided to get full credit.

The maximum credit possible without documentation is 80%.

The documentation needs to address at least the following points:

What were the main issues that had to be addressed and how did you address them?

Provide an overview of the structure of their program. How does the program work?

List any special features, bugs, etc. in the program. What did you learn with respect to the topics studied

in the class? Anything else you feel is important to discuss.

Project Part 1: A Virtual Machine Interpreter for BRAIN98

Step 1: Write a program that emulates a hypothetical computer, called BRAIN98. T

this virtual machine interprets BRAIN98 assembler code.

In general, you may write your emulator in the high-level language of your choice, but you must clear your choice of language with me first.

Project Part 1: A Virtual Machine Interpreter for BRAIN98

Step 2. Test your virtual machine with at least 3 non-trivial programs written in BRAIN98 machine language.

Note: “Non-trivial” means just that. It is unacceptable for your programs to simply

exercise the instruction set of the machine. Some good choices from past years include

computing Fibonacci numbers; multiplication of large (> 4 digits) numbers; sorting; prime number detection.

The Virtual Machine

Storage consists of a maximum of 100 words, addressed from 00 to 99;

each word is divided into four one-byte units, where a byte may contain any character acceptable by the host machine (i.e., the computer running the emulator).

The CPU has three registers: a four-byte (four-character, really) general register R, a one-character “Boolean” toggle C, which may

contain either “T” (true) or “F” (false), and a two-character instruction counter IC.

A word in memory may be interpreted as an instruction or data word.

If the word is an instruction, the operation code (“opcode”) occupies the two

high-order bytes of the word, and the operand address (if needed) appears in the

two low-order bytes. The virtual machine will assume that the first

instruction of the program appears in location 00 of memory.

Instruction Result Description

LR loc R := [loc] Load register LL loc R := R:1||R:2||[loc]:3||[loc]:4 Load low

(low-order bytes of R) LH loc R := [loc]:1||[loc]:2||R:3||R:4 Load high SR loc [loc] := R Save register CE loc if R = [loc] then C := ’T’ else C := ’F’ Condition equal CL loc if R < [loc] then C := ’T’ else C := ’F’ Condition less than BT loc if C = ’T’ then IC := loc Branch true (to loc) BU loc IC := loc Branch unconditional GD loc for i=0 to 10

(loc - (loc % 10)) + i:= data from file Get data: e.g., if loc = 43, then this reads the next 10 data items from the file and puts them in 40– 49

PD loc for i=0 to 10 Print data at (loc - (loc % 10)) + i Print 10 values in memory. If loc = 58, then this will print mem loc. 50-

59. AD loc R := R + [loc] Add SU loc R := R - [loc], R >= [loc] Subtract MU loc R := R * [loc] Multiply DI loc R := R / [loc], [loc] > 0 Divide NP loc none Null operation (no-op) H machine stops Halt (does

not require an operand)

loc is a two-character memory address, [loc] means the contents of memory location loc, [loc]:i means the ith character of the contents of loc,

where the characters are numbered 1234, R is the register, R:i means the ith character of the contents of the

register, IC is the instruction counter, C is the Boolean toggle, || means concatenation

R:1||R:2 means the first byte of R concatenated with the second byte of R.

Notes on Arithmetic Operations (AD,SU,MU,DI)

An arithmetic op on non-numeric data fields is undefined.

Divide by zero is undefined. A negative result (for SU) is undefined. Overflow values (for AD and MU) are lost. Important:

Undefined behavior can be handled by the implementer in any reasonable way.

Your program will read BRAIN98 input from a file. It will act both as a loader for the virtual machine and as an I/O processor.

The BRAIN98 input file has the format: Line 1: Header, identifying the kind of file it is. This is the

string “BRAIN98”, with the “B” starting in column one. Lines 2–n − 1: The BRAIN98 program.

Enter instructions as 4-character strings, one per line, starting in the first character of the line, with no blanks between the operator and operand.

After at least one blank, a non-interpretable comment may complete the line.

Whatever is in the first four characters of each of these lines will be loaded by your program into the corresponding memory location of the virtual machine.

Line n: Data separator. This line separates the BRAIN program from the data that will be read by GD instructions. This line consists of the string “DATA”, with the “D” starting in column 1.

Lines n+1–end of file - 1: Data. Each of these lines contains 10 input items (i.e., 10 4-characterwords of data) to be loaded into the virtual machine’s memory by GD instructions.

There are no spaces between words on this line. Note that this means that the first forty characters of the line, regardless of what is in them, is considered data!

Last line: This is the end-of-file indicator for your program. It consists of the string “END”, with the “E” beginning in column 1. In later parts of the project, the format will be changed to allow multiple BRAIN programs to reside in a single file.

Deliverables

Project demonstration Hardcopy of:

BRAIN source BRAIN98 program source code Documentation as discussed above. See syllabus for

the policy about grammar/spelling/typos. You will turn in the electronic version of your

project electronically via Blackboard (or equivalent).

Grading

Program (interpreter): 75% BRAIN programs: 15% Write-up: 10%

Recall Parameters to main in C.

main(int argc, char *argv[]) //also char *envp[]

{ ………………………………..}

argc: Number of command line parameters (always at least 1).

argv: Array of pointers to command line parameters. Each parameter is a null terminated string.

Example: % ./a.out 1 4

main(int argc, char *argv[])

{ ………………………………..}

argc = 3

argv points to an array with three elements, each of which is a pointer to a null terminated string.

“a.out” “1” “4”

argv

Example: % ./a.out 1 4

Ex: Want to print out name of program (inefficiently):

char *ptr ;

ptr = argv[0] ;

while (*ptr != ‘\0’)

printf(“%c”, *ptr++) ;

The name of the program is always contained in element 0 of argv.

Exec Family of System Calls

Used to begin a processes execution.

Overwrites process (core) image of the calling process with that of called program.

Several flavors, use the one most suited to needs.

int execv( char *path, char *argvec[]) ;

• int execl(const char *path, const char *arg0, ..., const char *argn, char *

/* NULL*/);

exec Function calls

int execv( char *path, char *argvec[]) ;

path: Can be an executable program in your directory (application code) or a system program such as ls, cd, date, …………..

argvec: Array of pointers to NULL terminated strings. First element should always be the name of the

program, last element should always be NULL.

main (int argc, *argv[])

{ int my_pid ; char *args[3] ; my_pid = fork() ; if (my_pid ==0)

{ args[0] = “./a.out” ; executed by args[1] = “2” ; child process args[2] = NULL;

execv(“./a.out”, args) ; printf(“OOOpppssss.\n”) ;}

elseprintf(“Not a problem!\n”) ; executed by parent

}

Example fork/exec pair

Program a.out will begin to execute and will have the following parameters to main:

argc = 3.

argv[0] = ./a.out

argv[1] = “2”

Process Management System Calls

• wait() Blocks parent process until all child processes have terminated

• wait(pid) Blocks until a particular child process terminates.

• exit() Terminate the process and de-allocate its resources.

Very Simple Shell

while(1){ type_prompt() ;

read_command(command, parameters) ; if (fork() != 0) // I am the parent

wait() ; else

{ execv(command, parameters) ; printf(“OOOPPPSSS\”) ;}

}