computer organization
c m s c 311  
s u m m e r   2 0 0 2  

Project #1

Due Thursday, June 20, 11:59 PM (just before midnight)
Late Due Date Sunday, June 23, 11:59 PM (just before midnight)

Latest Posting: June 16, 2002 (11 AM)

Posted: June 14, 2002

Addendum

Read this section frequently to check for updates/corrections/clarifications to the projects.

These are clarifications to various project specs.

Clarifications

Purpose

The goals of the project are:

Academic Integrity Statement

Please note that *all* programming projects in this course (including this one) are to be done independently or with the assistance of the instructional staff of this course only, unless otherwise specified IN PRINT by official webpages.

Please review the policies outlined on the class syllabus concerning the use of class computer accounts and concerning the University's Code of Academic Integrity. The instructors of this course will review the programs submitted by students for potential violations of the Code of Academic Integrity and if it is believed that a violation has occurred it will be referred to the Office of Judicial Programs and the Student Honor Council.

Hardcoding is considered a violation of academic integrity

Terminology

A list of terms that might be useful.

Overview

The goal of the project is to process an assembly language program stored in a file.

This program is divided into two parts: the data segment and the text segment. Think of the data segment as the variable declaration section, and the text segment as the actual code.

Your goal is to determine where in memory the data and the code will be stored, subject to certain restrictions. You won't actually run the program, nor store the data (although, it won't hurt to store the data since you'll actually run the program next time).

The program is expected to run in the following way.

Thus, there are at least two files: the assembly language file, and the command file. The assembly lanugage file is opened using whatever method the language you use opens files (fstream, etc).

The command file is processed by reading from standard input, so this will be redirected to test your code.

In particular, these are the tasks you need to do.

  1. Determine which file to load. This may be specified in the command line or in the commands file (sent to your program via input redirection.
  2. Determine which address in memory the data and code segment will start (there are two addresses: one for data, and one for the code). This information for these addresses are either provided in the command line and/or in the commands file.
  3. Process the commands.

Basic Assembly Language Program Layout

As assembly language program (at least, for the purposes of this class) consists of a data segment and a text segment.

The data segment is essentially where "variables" (actually, labels) are "declared and initialized".

The text segment is the assembly language program.

It's somewhat analagous to C code where all variables must be declared at the beginning, and then the actual code appears afterwards.

Visually, the assembly language file looks like:

   .data

   #  LABELS appears in this section

   .text

   #  assembly language program here

Data Segment

The data segment starts off with the phrase ".data". This is how you know you are in the data segment.
    .data
There may be leading spaces before and after the word. There may be blank lines before and afterwards.

After this line, there are a list of labels. Labels are somewhat like variables. Each label is associated with a memory location, which has to be calculated. The address depends on the type of data that is stored, as well as previous data that's already been computed.

Example and Syntax

Here's an example:

value: word 23
Let's see what this means:

When does a label end?

Since the labels may span more than one line, and there may be blank lines, how do you determine when the label ends? There are two ways. Either the next label starts (and the next label is always at the beginning of a line, preceded by possible blank spaces), which indicates the current label is complete.

Or, the ".text" segment begins.

Parsing algorithm

Here's a simple algorithm to help you parse labels.

Description of "Types"

Here are the possible types:

Type Explanation Syntax
word Stores one word. Must be word aligned. word <word-value>?
word array Stores an array of words. Must be word aligned. word [<digits>] <word-pattern>?
byte Stores one byte. byte <byte-value>?
byte array Stores an array of bytes byte [<digits>] <byte-pattern>?
string Stores C-style string string "<string>"

Let's look at each type more carefully:

Text Segment

After the data segment is the text segment. That part of the assembly language file begins with: .text This appears on a line and may have leading or trailing white space. This indicates the first line of the assembly language program.

Each line of text consists of

Each instruction lies on one line. Thus, for simplicity, instructions will never span more than one line of input.

You need to determine the following:

Each instruction is word-aligned and takes up 4 bytes of memory. In general, you should only worry about lines with instructions when determining which address they are stored in.

Labels have the same address as the instruction immediately after it. It is possible to have several labels in a row as in:

label_1:
label_2:
label_3: add $r1, $r2, $r3
All three label are at the same address as the add instruction.

It is also possible that a label does not have an instruction following it. This only happens if the label is at the very end after the last instruction. In that case, the address of that label should be the address of the last instruction plus 4.

For the time being, don't worry about what each instruction actually does. All you need to worry about are instructions that start with j, jal, beq, bne and determine the location of the label in those instructions.

As you process labels or instructions containing labels, you should do the following:

  1. Record the instruction in an array (or vector) of instructions.
  2. If it's a label, record the address with the label.
  3. If the label is within an instruction, determine whether you've seen the label yet (it may have come earlier). If not, wait until later when you've seen the label, and fix that instruction.

It's a good idea to save the instructions in some format (perhaps make an Instruction class).

Task

For instructions that are branch/jump instructions, add a comment to the end that says

You can assume that the label exists. However, for extra credit, you can indicate there's an error when the label does not exist. This will be discussed later on.

Computing Jump/Branch Instructions

Consider the following instructions:
foo:  add $r1, $r1, $r2
      add $r1, $r1, $r2

      beq $r1, $r2, foo   # jump -3
      jal bar             # jump +1
      add $r1, $r1, $r2
bar:  
      j foo               # jump -6
Let's label each instruction starting at 1. Since there are 6 instructions, the instruction are numbered from 1 to 6.

To determine the jump, find out the instruction of the jump/branch instruction. For example, jal bar is instruction 4. Add 1 to this to get 5. (The computation of the jump is relative to the next instruction).

Find the instruction of the label. In this case, bar is at instruction 6. So, 6 - 5 = 1, so jump +1.

It may seem odd to compute the jump from the next instruction, but there's a reason, which we'll discuss in later project.

Command Line Arguments

Normally, when you run an executable, you run it like:
  p0
or like
  p0 < primary.in
However, you can have arguments to the executable. These are called command line arguments.

  p0 -d 1000 -t 2000 -f in.file
where -d, -t, and -f are called switches or options. Each of these options have a single argument after it.

How to read command line arguments

If you are programming in C/C++, the command line arguments are read in by modifying main() as follows:
int main( int argc, char *argv[] )
where argc counts the number of arguments and the command itself. So, p0 -d 1000 -t 2000 -f in.file would have argc = 7. argc stands for "argument count". It uses white space to determine how to split the line apart (but groups things in quotes as one argument).

argv is an array of char * (i.e. C-style) strings. The array's size is one larger than argc. For example argv[ 0 ] == "p0", argv[ 1 ] == "-d", argc[ 2 ] == "1000", and so forth. argv[ 7 ] == NULL.

Notice argv[ 0 ] is the name of the executable. Also notice that all commands are C-style strings. Thus "1000" is a C-style string, not an int.

In Java, command line arguments are read in as:

public static void main( String args[] )
where the arguments begin at the actual argument and NOT at the name of the command. Thus, java Foo -d 1000 -t 2000 -f in.file starts the arguments at -d, NOT at Foo.

Removing Comments

You should be able to remove comments. To do so, you should read in one line of text, search for the first occurrence of "#", and find a substring from the beginnning of the line up to but not including "#".

Comments can appear at the end of the line or on its own line.

Example

To make it easier to follow what's going on, let's look at an example.

Suppose the user types in:

p1 -d 999 -t 2001 -f sample.asm < primary.in
What does this mean?

Here's a sample assembly language file:

  .data

val:  word -12
arr:  byte [7] 
arr2: word [10] 9**
char: byte '\n'

  .text

BAR:  add $r1, $r2, $r3
      j FOO
      add $r1, $r2, $r3
      jal END
FOO:  add $r1, $r2, $r3
      beq $r1, $r2, BAR
END:   

The file consists of the data segment, then the text segment.

Let's go through the steps to see what to do.

  1. First, you recognize find .data and begin to process the data segment.
  2. You know the start address for the data segment is 99910 based on the command line argument.
  3. You see the label val. It is a word so it must be word-aligned, which means that val must be stored at the next higer address that is divisible by 4. That is address 100010 (which you need to convert to hexadecimal).

    val takes up 4 consecutive bytes. You print out the appropriate message.

  4. Now, you handle arr. This is a byte array. It takes up 7 bytes, and does not have to be word-aligned. So, 100410 is the first location after word. You can place the byte array there. It occupies address 100410 through 101010 (inclusive).

  5. Now, you handle arr2. This is a word array. It needs to be word-aligned. 101010 is not word-aligned (not evenly divisible by 4). So, pick the next available address that's word-aligned: 101210.

    The array is 10 words long, so that uses 40 bytes. Thus, addresses 101210 up to 105110, inclusive.

  6. Finally, handle char, which is a single byte. This can go at address 1012.

Note: for simplicity, you don't go back to empty gaps that weren't assigned, (for example, char is not placed at address 999, which wasn't used). You just proceed to the next unused spot in memory.

At this point, you see .text and know it's time to begin processing the assembly language code. This part should be easier.

In particular,

Instructions need to be word aligned, so they should start at addresses divisible by 4. Since the address starts at 2001, you need to begin the code at 2004 which is divisible by 4.

Which Language?

I would prefer that you choose between C, C++, or Java. If you want to pick any other language, please seek prior approval. In particular, the language should support bitwise operations and arrays, or you should be able to simulate them in some fashion.

What's this for?

In this project, the code isn't run, and it isn't even necessary to store the data in memory locations (they can be processed just enough to print it, and then you can discard them). The goal is merely to determine where to place the data/code once it comes time to do so.

Think of it like planning a wedding banquet. You are trying to figure out which seats each guest should sit (determining who sits near the front, who sits at which table). You're not actually placing the guests there until they arrive. All you're doing is planning it.

Similarly, this project is about planning where to put the data and code in memory.

Commands

In this project, there are two commands.

After each command, print:

===> (1) You entered: [quit]
   Exiting program.
or
===> (1) You entered: [load -d 1000 -t 2000 -f file.asm]
The output for load is described below.

Notes on Commands

In the next project, there will be commands to determine the content of memory, registers, etc.

Output for "load"

Coming soon

Last modified: Sun Jun 16 03:18:20 EDT 2002

Web Accessibility