PROGRAMMING PROJECT 1b:
UTILITY FUNCTIONS FOR AN ASSEMBLER



Review Of: C

You should work individually on this project.



Label Table: Utility Functions for an Assembler

In this project you will complete a set of functions for constructing and using a table of labels and their addresses, which will be used later in Programming Project #3. C is not an object-oriented language, but the data structure and methods for the Label Table have been packaged together in files ("encapsulated" in OO terminology) in a way that is inspired by OO methods. (More information about this program appears below.)

The goal of the project is to gain more familiarity with C by writing some useful functions for a future programming project.

Files: You should put these files in a different directory than your Disassembler files, so that you don't have naming conflicts, especially with the Makefile. (Note that although this Makefile is different, the printDebug, printError, and process_arguments functions are the same.)

Some other files that will be useful are:

The Makefile contains information for the make command, telling it how to compile this program (and the future assembler program). (Type make at a command-line prompt or, if you are using an IDE, your IDE may be able to use makefiles.) The Makefile for this program illustrates separate compilation of object files (e.g., LabelTable.o) before creating an executable. With this style of makefile, only the files that have been changed are re-compiled before the relevant object files are linked together into the executable. The resulting Makefile is longer, but more efficient.

The make command will create a compiled executable called testLabelTable. You can run your program by typing its name at the command line. If you don't want to have to keep typing ./testLabelTable, edit the makefile and change the name of the executable at the end of the gcc command to something shorter, like pp1b or even just tlt:

    gcc ... -o tlt

You can run the program, but it won't do anything visible until some appropriate test cases have been added to the main function. (Note: this program, unlike PP #1a, does not take an optional filename as an argument, although you can still turn on debugging at the command line. See the box about printDebug below for more information.)

Project Description:

Later in the quarter you will be writing an assembler program. One of its associated data structures is a table containing instruction labels and their corresponding addresses. For example, if the instruction at address 1600 is labeled "StartLoop", then the label table should contain the following entry:

     StartLoop        1600

LabelTable.c contains templates or incomplete versions of a number of functions for initializing such a table, resizing it, adding a new entry, finding the address for a particular label name, and printing the contents of the table. LabelTable.h and LabelTable.c provide more complete specifications for these functions. (tableResize is complete; the other functions are not.)

Start by implementing and testing the printLabels function, so that you can use it to help you in testing the other functions. You can use the testLabelTable.c test driver provided above for your testing. This driver has a small, simple static table structure already set up, that you can use for your initial tests. The printLabels function should print all the labels in the table, along with their associated addresses. You should provide descriptors for each field to make the table more readable (either column headings or immediately before the fields, e.g., "Label: StartLoop"). Next, you should implement and test the findLabel function. The test driver file above contains an incomplete helper function, testSearch, that should call findLabel and print the address associated with the given label if the search was successful. Update the testSearch function in the test driver and call it from main to test the findLabel function in LabelTable.c.

Note that the printLabels function and the findLabel function are the only LabelTable functions that should be called on the static table structure provided to you.

If you want to add extra, informative statements to your code that will be helpful when you are debugging, but that you do not want to be part of the final output, you can use the printDebug function provided in one of the files above. printDebug takes the same type of arguments as printf, but it only prints the messages when debugging has been turned on. (And it prints to stderr rather than stdout.)

One way to turn debugging on is to add a call to debug_on() to your testLabelTable.c file, right after the call to process_debug_choice. See the printFuncs.h header file for more information about debug_on(), debug_off(), printDebug(), and several other, related functions.

Another way to run your program with debugging on is to call the program with an argument that specifies the debugging state. For example,

    testLabelTable 1
will run the program with debugging turned on (regardless of any calls to debug_on and the like in your code), while calling testLabelTable 0 will run the program with debugging turned off. (The process_debug_choice function in the test driver handles this; it looks to see if a debug flag is being passed to the program as an argument, and, if so, sets the debugging state accordingly.) If you don't specify the debugging state on the command line, your program will use calls to debug_on(), etc. to decide whether or not to print messages passed to the printDebug function.

When you move on to the functions that work with dynamically-allocated table entries (tableInit, tableResize, and addLabel, make sure the resizing of the table in addLabel will work correctly even when adding the first label. In the test driver, you should not try to test these functions using the static array of label entries; instead, create a new LabelTable, initialize it using tableInit, and add entries using addLabel (which should call tableResize if necessary).

Note: the code in LabelTable.c dynamically allocates space for the array of table entries, but not for the top-level table structure itself. Each table function expects a pointer to an existing table structure as its first parameter.

Ensuring Quality

As specified in the syllabus, your program should adhere to the Kalamazoo College CS Program Style Guide and Documentation Standards, including use of the Braces Line Up style pattern.

To ensure that all function calls are syntactically correct (match the function definitions), you should include function declarations for all of your functions in one or more header files, and include the header file(s) in all appropriate C source files (*.c files).

The Makefile I have provided specifies a set of compiler options that will help you catch many errors at compile time. These options generate warnings about questionable constructions that often indicate programmer confusion or actual logic errors. You may have to make adjustments to the Makefile, though, if the specific options or option names for your compiler are somewhat different.

Be sure that your final test program tests all of the functions in LabelTable.c, including boundary conditions (table is empty, full to capacity, adding a label beyond the current capacity, etc.).

Submission Requirements:

You should submit a zip (or tar or 7z) file that contains:

(Notes: Before zipping up your directory, please rename it to start with your first name, e.g., Alyce_PP1b, so that I don't have a dozen folders with similar names. It is also a good idea to run make clean in the directory before zipping it up; this will remove the machine-specific executable and intermediate "object code" files, since your code will have to be re-compiled on my machine anyway.)

The rubric for grading Programming Project #1b will based on the following.

  PP1b -- Compiles and runs                                            5 pts
  PP1b -- Correctness (satisfies 17 specific criteria)                 17 pts
  PP1b -- Updated comments at top of LabelTable.c                      1 pt
  PP1b -- Test driver (include sufficient test cases)                  6 pts

  Total:                                                               29 pts

Note that roughly 20% of the points are related to testing.