Setting up Codio for this HW:
1) Open the Codio assignment via Coursera
2) From the Codio File-Tree click on: lc4_memory.h and lc4_memory.c
3) Remember to use the Codio “Pre-submission tests” function before submitting the assignment.
Overview:
The goal of this HW is for you to write a program that can open and read in a .OBJ file created by PennSim, parse it, and load it into a linked list that will represent the LC4’s program and data memories (similar to what PennSim’s “loader” does). In the last HW, you created a .OBJ file. In this HW, you will be able to read in a .OBJ file and convert it back to the assembly it came from!
This is known as reverse assembling (sometimes a disassembler).
RECALL: OBJECT FILE FORMAT
The following is the format for the binary .OBJ files created by PennSim from your .ASM files. It represents the contents of memory (both program and data) for your assembled LC-4 Assembly programs. In a .OBJ file, there are 3 basic sections indicated by 3 header “types” = CODE, DATA,SYMBOL.
This corresponds to the .CODE directive in assembly.
LINKED LIST NODE STRUCTURE:
In the file: lc4_memory.h, you’ll see the following structure defined:
The structure is meant to model a row of the LC4’s memory: a 16-bit address, & its 16-bitcontents. As you know, an address may also have a label associated with it. You will also recall that PennSim always shows the contents of memory in its “assembly” form. So PennSim reverse-assembles the contents and displays the assembly instruction itself (instead of the binary contents).
As part of this assignment, you will read in a .OBJ file and store each instruction in a NODE of the type above. Since they’ll be an unknown # of instructions in the file, you’ll create a linked list of the nodes above to hold all the instructions that are in the .OBJ file.
The details of how to implement all of this will be discussed in the sections of this document that follow.
IMPLEMENTATION DETAILS:
The first files to view in the helper file are lc4_memory.h and lc4_memory.c. In these files you will notice the structure that represents a row_of_memory as referenced above (see the section: LINKED_LIST_NODE_STRUCTURE above for the node’s layout). You will also see several helper functions that will serve to manage a linked list of “rows_of_memory” nodes. Your job will be to implement these simple linked list helper functions using your knowledge from the last HW assignment. You must implement everything listed by the comments in the starter code.
Next, you will modify the file called: lc4.c It serves as the “main” for the entire program. The head of the linked list must be stored in main(), you will see in the provided lc4.c file a pointer named: memory will do just that. Main() will then extract the name of the .OBJ file the user has passed in when they ran your program from the argv[] parameter passed in from the user.
Upon parsing that, it will call lc4_loader.c’s open_file() and hold a pointer to the open file. It will then call lc4_loader.c’s parse_file() to interpret the .OBJ file the user wishes to have your program process. Lastly it will reverse assemble the file, print the linked list, and finally delete it when the program ends. These functions are described in greater detail below. The order of the function calls and their purpose is shown in comments in the lc4.c file that you will implement as part of this assignment.
Once you have properly implemented lc4.c and have it accept input from the command line, a user should be able to run your program as follows:
./lc4 my_file.obj
Where “my_file.obj” can be replaced with any file name the user desires as long as it is a valid .OBJ file that was created by PennSim. If no file is passed in, your program should generate an error telling the user what went wrong, like this:
error1: usage: ./lc4 <object_file.obj>
There is no need to check that the filename ends in .obj nor should you append .obj to filename passed in without an extension.
Problem 1) Implementing the LC4 Loader
Most of the work of your program will take place in the file: called: lc4_loader.c. In this file, you will start by implementing the function: open_file() to take in the name of the file the user of your program has specified on the command line (see lc4_loader.h for the definition of open_file()). If the file exists, the function should return a handle to that open file, otherwise a NULL should be returned.
Also in lc4_loader.c, you will implement a second function: parse_file() that will read in and parse the contents of the open .OBJ file as well as populate the linked_list as it reads the .OBJ file. The format of the .OBJ input file has been in lecture, but its layout has been reprinted above (see section: OBJECT_FILE_FORMAT). As shown in the flowchart above, have the function read in the 3-word header from the file. You’ll notice that all of the LC4 .OBJ file headers consist of 3 fields: header type, <address>, <n>. As you read in the first header in the file, store the address field and the <n> field into local variables. Then determine the type of header you have read in: CODE/DATA/SYMBOL.
If you have read in a CODE header in the .OBJ file, from the file format for a .OBJ file, you’ll recall the body of the CODE section is <n>-words long. As an example, see the hex listed below,this is a sample CODE section, notice the field we should correlate with n=0x000C, or decimal:12.This indicates that the next 12-words in the .OBJ file are in fact 12 LC-4 instructions. Recall each instruction in LC4 is 1 word long.