Programming Project: Disassembler Utility Functions



The goal of the project is to gain more familiarity with C by writing two utility functions that will be useful for processing the input for a disassembler (the subject of a future project). You will also develop test cases to test your two functions. The actual specifications for the program appear below in the Description section.

You may work on this project individually or in groups of two.


The DisUtil Repository:

Clone the DisUtil repository from Kit. This repository has a number of starter files in it. You will be modifying some, and using others.

Files You Will Modify:

Other Useful Files:
  • Makefile: specifies how to compile both this program and the future disassembler program
  • disUtil.h (a header file for this program)
  • process_arguments.c (function that processes command-line arguments passed to the main function; used in test driver; has an associated process_arguments.h header file)
  • same.c (defines a constant called SAME used by process_arguments; has an associated same.h header file)
  • printFuncs.h (a header file for the following two print functions)
  • printDebug.c (prints debugging messages; used in test driver)
  • printError.c (prints error messages; used in verifyMIPSInstruction)

Running the Starter Code:

The provided code should compile and run, although it does not yet have the functionality this program should have.

The Makefile contains information for the make command, telling it how to compile this program (and the future disassembler program). To compile this program, type make at a command-line prompt. If you are using an IDE, your IDE may be able to use makefiles.

The make command will create a compiled executable called disUtil. You can run your program by typing its name at the command line. It takes two optional parameters: a filename and an integer 1 if you want to turn on debugging. If you run the program with the minimalist starter test file provided above, you'll see that for now it just prints a 5-character substring of each line in the test file. (To start with, the program will claim that each substring represents the value 0, regardless of what the value really is.)

    ./disUtil testfileStarter.txt    run the program with the given test file
    ./disUtil testfileStarter.txt 1  ... and with debugging on

You can modify the testfileStarter.txt test file and run the program again to see how its behavior changes. (The test file is just made of plain ASCII text, so you can modify it with any program that allows you to edit plain text files. Note that C source files are also plain text files, so you can use whatever you use to edit C source files to also edit test files.) Test the program with and without the second parameter, 1.

Project Description/Specification:

The input file for our future disassembler will contain strings representing MIPS machine code, one instruction per line. Actual MIPS instructions would be stored in 32-bit integers; instead, our file will contain lines of 32 characters ('0' or '1'), where each line represents the 32 bits in a machine language MIPS instruction ("pseudo-binary").

Example input line: 01010101000000000000010101010110

If that string represented 4 8-bit positive integers, we could interpret it as representing the 4 decimal numbers 85, 0, 5, 86. (01010101 00000000 00000101 01010110)

The purpose of the functions you are completing in this project is to read in the strings representing MIPS machine code, make sure they are valid, and decode string subsets in decimal format.

main:

The main function in the test driver (disUtilDriver.c) currently reads lines in from a file until reaching the end of the file. If the line ends with a newline, the program strips the newline from the string by replacing it with a null byte. It then calls verifyMIPSInstruction (currently just a skeleton) to verify that the string format is appropriate for a MIPS machine code instruction, or to print an error otherwise. If the instruction format is valid, main calls testBinToDec, which in turn calls binToDec (which is also currently just a stub).

You can leave main as it is for now, while you complete and test verifyMIPSInstruction. Once you have completed the binToDec function, you will need to modify the main function to call testBinToDec several times with various parameters, to test binToDec effectively and print the results. (Currently main only calls testBinToDec once.)

verifyMIPSInstruction:

The verifyMIPSInstruction function should verify that the string provided to it is 32 characters long and that the characters in the string are all 0's or 1's (character '0' or character '1'). If the instruction is valid, verifyMIPSInstruction should return 1. Otherwise, it should print an error message indicating the error and the line on which it occurred before returning 0.

Test your modifications before going further by adding appropriate data to the existing test file or by creating new data files. Run the program with debugging turned on to see your test results. (See the section above on running the program.) Be sure to include tests cases that exercise every path through your code as well as all appropriate boundary conditions (e.g., empty lines, too-long lines, invalid data in the first / last positions, etc.).

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.

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.

binToDec:

The binToDec function should interpret a substring of characters in an array as a binary number, convert it to an integer, and return the integer. The first parameter is the array of characters; the second and third parameters are the beginning index and ending index of the substring. For example, assume A is a character array that contains the following characters.

       1 0 1 1 0 1 0 0 1
The call binToDec(A, 2, 5) should convert the string of binary digits '1' '1' '0' '1' (the substring A[2] - A[5], inclusive) to the integer 13 and return it. One approach, using an algorithm for converting a binary number to a decimal number, involves evaluating the binary value from the least significant digit to the most significant digit, adding in (or not) the appropriate power of two to the decimal value. Rather than calculating the power of two for each digit, you can store the power of two in a variable and multiply it by two when you go to the next digit. (What should the power-of-two variable be initialized to for the least significant digit?)

To test binToDec thoroughly, you should modify main to call testBinToDec in a number of different ways, rather than just once. Think particularly about what kinds of boundary conditions you should test for.

Alternatives: There's a similarly efficient algorithm that processes the binary digits left-to-right, multiplying the decimal value by two each time it goes on to the next binary digit. Or, if you are interested in using the C left-shift operator, you can use that instead.

Submission Requirements:

Your submission should contain;

Your program should also work with other input files that may be developed for consistent grading. (Note: It is a good idea to run make clean in the directory before submitting; this will remove the machine-specific executable and intermediate "object code" files, since your code will have to be re-compiled on the grader's machine anyway.)

Rubric:

The rubric for grading this project is based on the following general categories.

  Compiles and runs                                             1 pt
  `verifyMIPSInstruction` functionality                         1 pt
  `binToDec` functionality                                      1 pt
  Comments, Documentation, Clean Programming Style              1 pt
  Test Cases for `verifyMIPSInstruction` (based on data file)   1 pt
  Test Cases for `binToDec` (based on calls to testBinToDec)    1 pt
  Reasonable efficiency                                         1 pt

Note that developing a thorough test suite is an important aspect of this assignment.