Data Structures | Macros | Typedefs | Functions | Variables
assembler.h File Reference

Defines the interface to assembler.c functions (do not modify) More...

#include <stdbool.h>
#include "lc3.h"
#include "symbol.h"

Go to the source code of this file.

Data Structures

struct  line_info
 

Macros

#define LC3AS_VAR   extern
 
#define ERR_OPEN_READ   "could not open '%s' for reading."
 
#define ERR_OPEN_WRITE   "could not open '%s' for writing."
 
#define ERR_LINE_TOO_LONG   "source line too long (max is %d)"
 
#define ERR_NO_ORIG   "no .ORIG directive found"
 
#define ERR_MULTIPLE_ORIG   "multiple .ORIG found"
 
#define ERR_NO_END   "no .END directive found"
 
#define ERR_ORIG_NOT_1ST   "instruction(s) appear before .ORIG"
 
#define ERR_END_NOT_LAST   "instruction(s) appear after .END - ignored"
 
#define ERR_EXPECTED_COMMA   "expected comma, got '%s'"
 
#define ERR_EXPECTED_REG   "expected register (R0-R7), got '%s'"
 
#define ERR_EXPECT_REG_IMM   "expected register or immediate, got '%s'"
 
#define ERR_BAD_LABEL   "label '%s' contains illegal characters"
 
#define ERR_MISSING_OP   "expected LC3 op, got '%s'"
 
#define ERR_MISSING_OPERAND   "too few operand(s)"
 
#define ERR_EXTRA_OPERAND   "extra operand(s) '%s'"
 
#define ERR_DUPLICATE_LABEL   "label '%s' previously defined"
 
#define ERR_MISSING_LABEL   "label '%s' never defined"
 
#define ERR_BAD_PCOFFSET   "PCoffset to '%s' out of range"
 
#define ERR_BAD_IMM   "immediate '%s' (bad format)"
 
#define ERR_IMM_TOO_BIG   "immediate '%s' out of range"
 
#define ERR_EXPECTED_STR   "expected quoted string, got '%s'"
 
#define ERR_BAD_STR   "unterminated string '%s'"
 
#define ERR_EXPECTED_FILL   "expected .FILL value, got '%s'"
 
#define ERR_BAD_CHAR_CONST   "incorrect character constant \"%s\""
 

Typedefs

typedef struct line_info line_info_t
 

Functions

void asm_error (const char *msg,...)
 
line_info_tasm_init_line_info (line_info_t *info, const char *opTok)
 
void asm_print_line_info (line_info_t *info)
 
void asm_init (void)
 
line_info_tasm_pass_one (const char *asm_file_name, const char *sym_file_name)
 
void asm_pass_two (const char *obj_file_name, line_info_t *list)
 
void asm_term (line_info_t *list)
 

Variables

LC3AS_VAR int numErrors
 
LC3AS_VAR int printPass1
 

Detailed Description

This file defines the interface to a C file assembler.c that you will complete. This is the main portion of an assembler for LC3.

This is a substantial assignment. One way to attack larger projects is to break the problem into pieces and code those pieces individually. You have already done this for the files util.c and symbol.c. Instead of writing large functions (e.g. asm_pass_one(), asm_pass_two()), decompose them into a series of calls to shorter functions which do required subtasks. The decomposition may be continued until each low level function is easy to write correctly. If you find any one function getting "too" large, think about what the code does and decompose it into several smaller functions. In fact, if you can give the task a good symbolic name, you can postpone writing it until later. This is because the name implies "what" the function does. "How" it is done, will be determined when that function is coded. It is perfectly fine to have functions that are only called once from the code. The idea is that each of these functions peform a straight forward subtask. And it is perfectly fine to have functions that are only one or a few lines of code.

A good rule of thumb is that a function is too large if you can not see the entire function on a single page.

Author
Fritz Sieker

Macro Definition Documentation

#define ERR_OPEN_READ   "could not open '%s' for reading."

Error messages passed to function asm_error()

#define LC3AS_VAR   extern

Handy way of defining global variable in a header file

Typedef Documentation

typedef struct line_info line_info_t

Typedef of structure type

Function Documentation

void asm_error ( const char *  msg,
  ... 
)

A function to print error messages. This function takes a minimum of one parameter. It is exaclty like the printf() function. The first parameter is a formatting string. This will be one of the values defined above that starts with ERR_.The remaining parameters (if any) are the actual values to be printed (generally a token). The function prints the word ERROR: and the the value of srcLineNum along with the information provided by the parameters. It must be used for reporting all errors. After printing the error, the global variable numErrors is incremented. This function relies on the static variable srcLineNum in assembler.c. Suppose one wanted to report that a file could not be opened for reading. The C code might look line this.

FIlE* f = fopen(filename, "r");
if (f == NULL) {
  asm_error(ERR_OPEN_READ, filename);
  // any other actions 
}

Ideally, this function would throw an exception.

Parameters
msg- the formating string (one of the ERR_xxx macros)
...- a list of values to be substitued into the format string.
void asm_init ( void  )

Do whatever initialization is necessary for the assembler

Todo:
implement this function
line_info_t* asm_init_line_info ( line_info_t info,
const char *  opTok 
)

A function to initialize all the fields of the structure to default values. Since C does not have constructors, it is convenient to write functions to initialize fields of a structure to default values. The first parameter allows the function to be used in two ways. If its value is NULL, the structure is malloc()-ed. If it is not NULL, the structure pointed to by the parameter is initialized. This allow the easy initialization of a local variabe in some other function by passing its address. The fields info->lineNum and info->address are initialized from global values defined in assembler.c. You may modify this function to do additional checks and initialization if you find that usefull. You may not change its signature. This function is only used in assembler.c and should be static. It is declared here for documentation purposes.

Parameters
infopointer to an existing structure or NULL
opTokthe string representing the operation (e.g. "ADD"
Returns
a pointer to the initialized structure
line_info_t* asm_pass_one ( const char *  asm_file_name,
const char *  sym_file_name 
)

This function performs the processing required in the first pass. At a minimum, it must check the syntax of each instruction and create the symbol table. For this assignment, it will also create a linked list for use by the second pass. The flow of this function is:

  1. open the source file and report any error
  2. read the lines one at a time using fgets()
  3. convert the line to a list of tokens
  4. if there is a label in the line, add it to the symbol table
  5. if there is an opcode (e.g. ADD) on the line, then
    1. allocate/initialize a new line_info_t structure
    2. convert the tokens to values and set the appropriate fields of the structure
    3. add the structure to the tail of the linked list
    4. update the current address
  6. If there were no errors, write the symbol table file using lc3_write_sym_tab().
  7. return the linked list
Parameters
asm_file_name- name of the .asm file to assemble
sym_file_name- name of the symbol table file
Returns
- a linked list of information about each source line
Todo:
implement this function
void asm_pass_two ( const char *  obj_file_name,
line_info_t list 
)

This function generates the object file. It is only called if no errors were found during asm_pass_one(). The basic structure of this code is to loop over the data structure created in asm_pass_one(), generate object code (16 bit LC3 instructions) and write it to the object file using lc3_write_LC3_word(). The function also calculates the PCoffset and verify that they are within range. Use the following formula for calculation:


targetAddress = instructionAddress + 1 + PCoffset

The targetAddress is found by looking up the reference in the symbol table. The instructionAddress is in the line_info_t structure. Note that the PCoffset only uses a subset of the bits in an LC3 instruction.

Parameters
obj_file_name- name of the object file for this source code
list- the linked list produced by asm_pass_one()
Todo:
implement this function
void asm_print_line_info ( line_info_t info)

A function to print the infomation extracted from a source line. This is used for debugging only.

Parameters
info- pointer to informaton about a source line
void asm_term ( line_info_t list)

Cleanup everything used by the assembler.

Parameters
list- the list produced by asm_pass_one()
Todo:
implement this function

Variable Documentation

LC3AS_VAR int numErrors

A global variable defining the number of errors found

LC3AS_VAR int printPass1

A global variable defining whether to print pass1 info