Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit

CIT 5930 Module 12 HW: C - File I/O – Making the LC4 Assembler

Due Date(s) Wednesday 11/30 @11:59pm via gradescope.com

NOTE: If your program is crashing, before you can be helped via TA office hours, YOU ARE REQUIRED TO RUN GDB on your program to

pinpoint the error.

NOTE: There wont be any office hours over the thanksgiving break,

please plan accordingly!

READING: Chapter 11 of the book (basics of C), Chapter 12 (variables), Chapter 16 (pointers & arrays) are excellent references for this homework assignment. If you have purchased a C-     programming book, then you’ll want to look to its chapter on strings in C.

Video Resources for this Assignment:

This assignment will be programmed in C and run on codio.  The following resources can help:

TUTORIAL-DEBUGGING in C: If you are getting segfaults during this HW assignment,        and having trouble with your program, watch this video on canvas to help you learn how to use the GDB debugger: Files->Resources->Tutorials->

Tutorial_Debugging_GDB.mp4

TUTORIAL-MAKEFILES: If you are still struggling to understand Makefiles even after the last assignment as well as recitation, try this video: Files->Resources->Tutorials->

Tutorial_Makefiles.mp4

(these are greyed out because you may have already watched them for the last HW, but this

is a reminder of their existence!)

Setting up Codio for this HW:

1)   Review the PennSimvideo tutorial, as we will use PennSim again in this HW

2)   Login to codio.com using the login you created in the previous HW and find assignment:

a.    From the CourseDropdown box in the middle of the screen, select:

b.   From the ModuleDropdown box in the middle of the screen, select:

c.    A list of assignments should appear, select:

3)   From the codio File-Tree” click on: assembler.c

Assignment Overview:

COMMENTS ARE NOT INCLUDED, QUICK TIPS HERE: https://www.devtopics.com/13-tips-to-comment-

your-code/

From lecture you’ve learned that C is file-oriented and that working with files represents I/O      devices in C.  C places files into two categories: “text” and “binary.”  In this assignment you’ll     work with both types by reading in a text file and writing out a binary file.  The text file that you will read in this assignment will be a .ASM file (a text file intended for PennSim) and the type of output file you’ll generate will be a .OBJ file ( the same type of binary file that PennSim would   write out).  Aside from reading and writing out the files, your task will be make a mini-LC4-         Assembler!  A program that reads in assembly language and generates its machine equivalent.  This assignment will require a bit more programming rigor than we’ve had thus far, but now      that you’ve gained a good amount of programming skill in this class and in others, it is the          perfect time to tackle a large programming assignment.

Problem #1: Reading in a text file (the .ASM file)

Open assembler.c” from the helper files; it contains the main() function for the program. Carefully examine the variables at the top:

char* filename = NULL ;

char  program [ROWS][COLS] ;

char  program_bin_str [ROWS][17] ;

unsigned short int program_bin [ROWS] ;

The first pointer variable “filename” will be a pointer to a string that contains the text file you’ll be reading.  Your program must take in as an argument the name of a .ASM file.  As an                example, once you compile your main() program, you would execute it as follows:

./assembler test.asm

In your last HW you learned how to use the arguments passed into main().  So the first thing to implement is to check if argc has arguments, and if it does, point “filename” to the argument   that contains the passed in string that is the file’s name.  You should return from main()             immediately (with an error message) if the caller doesn’t provide an input file name as follows:

error1: usage: ./assembler 

Start by updating assembler.c” to read in the arguments.  Compile your changes and test them before continuing.  You should take this moment to setup your Makefile as well, it should           contain two basic directives: assembler and asm_parser.o

After you’ve successfully gotten the filename from the caller, the first function you must call       will be:                                                                                                                                                               int read_asm_file (char* filename, char program [ROWS][COLS] ) ; The purpose of read_asm_file() is to open the ASM file, and place its contents into the 2D array: program[][].  You must complete the implementation of this function in the provided helper

file: “asm_parser.c” .  Notice, it takes in the pointer to the filename” that you’ll open in this     function.  It also takes in the two dimensional array, program, that was defined back in main(). You’ll see that “ROWS” and “COLS” are two #define’ed constants in the file: asm_parser.h.       Rows is set to 100 and COLS is set to 255.  This means that you can only read in a program that is up to 100 lines long and each line of this program can be no longer than 255.                            You’ll want to look at the class notes (or a C-reference textbook) to use fopen() to open the      filename that has been passed in.  Then you’ll want to use a function like: fgets() to read each  line of the .ASM file into the program[][] 2D array.  Be aware that “fgets()” will keep carriage    returns (aka – the newline character) and you’ll need to strip these from the input.                     Take a look at test.asm file that was included in the helper file.  It contains the following            program:                                                                                                                                                         ADD R1, R0, R1                                                                       MUL R2, R1, R1                                                                       SUB R3, R2, R1                                                                       DIV R1, R3, R2                                                                       AND R1, R2, R3                                                                       OR R1, R3, R2                                                                        XOR R1, R3, R2                                                                       After you complete read_asm_file() and if you were to run it on test.asm, your 2D array:           program[][]should contain the contents of the ASM file in this order:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

A

D

D

R

1

,

R

0

,

R

1

\0’

M

U

L

R

2

,

R

1

,

R

1

\0’

S

U

B

R

3

,

R

2

,

R

1

\0’

D

I

V

R

1

,

R

3

,

R

2

\0’

A

N

D

R

1

,

R

2

,

R

3

\0’

O

R

R

1

,

R

3

,

R

2

\0’

X

X

O

R

R

1

,

R

3

,

R

2

\0’

\0’

X

X

X

X

X

X

X

X

X

X

X

X

X

X

Notice, there are no “newline” characters at the end of the lines.

If reading in the file is a success, return 0 from the function, if not, return 2 from the function

and print an error to the screen:  error2: read_asm_file() failed

Implement and test this function carefully before continuing on with the assignment.

Problem #2: Parsing an Instruction

Once read_asm_file() is working properly, back in main(), you’ll call the function:

parse_instruction(), which is also located in asm_file.c:

int parse_instruction (char* instr, char* instr_bin_str) ;

purpose, arguments & return value

The purpose of this function is to take in a single row of your program[][] array and convert to its binary equivalent in text form.  The argument: instr must point to a row in main()’s 2D     array: program[][].  The argument: instr_bin_str must point to the corresponding row in           main()’s 2D array: program_bin_str[][].  If there no errors are encountered the function will    return a 0 and if any error occurs (in this function) it should return the number 3 and an error message should be printed: error3: parse_instruction() failed.

Let’s assume you’ve called parse_instruction() and instr” points to the first row in your program[][] array:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

A

D

D

H

1

,

H

0

,

H

1

/0’

Parse_instruction() needs to examine this string and convert it into a binary equivalent.  You’ll need to use the LC4 ISA to determine the binary equivalent of an instruction.  When your        function returns, the memory pointed to by: instr_bin_str, should look like this:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

0

0

0

1

0

0

1

0

0

0

0

0

0

0

0

1

/0’