My Project
|
definitions of the LC3 instruction set architecture (ISA) (do not modify) More...
Go to the source code of this file.
Data Structures | |
struct | inst_format |
struct | LC3_inst |
Macros | |
#define | LC3_VAR extern |
#define | LC3_WORD unsigned short |
#define | LC3_MEM_SIZE (1 << 16) |
#define | LC3_NUM_REGS 8 |
#define | RETURN_ADDR_REG 7 |
Typedefs | |
typedef enum opcode | opcode_t |
typedef enum operand | operand_t |
typedef enum format | format_t |
typedef struct inst_format | inst_format_t |
typedef struct LC3_inst | LC3_inst_t |
Enumerations | |
enum | opcode { OP_INVALID = -1, OP_BR, OP_ADD, OP_LD, OP_ST, OP_JSR_JSRR, OP_AND, OP_LDR, OP_STR, OP_RTI, OP_NOT, OP_LDI, OP_STI, OP_JMP_RET, OP_RESERVED, OP_LEA, OP_TRAP, OP_ORIG, OP_END, OP_BLKW, OP_FILL, OP_STRINGZ, OP_GETC, OP_OUT, OP_PUTS, OP_IN, OP_PUTSP, OP_HALT, OP_GETS, OP_NEWLN, OP_ZERO, OP_COPY, OP_SETCC, OP_SUB, NUM_OPCODES } |
enum | operand { OPN_DR = 0x0001, OPN_SR1 = 0x0002, OPN_SR2 = 0x0004, OPN_CC = 0x0008, OPN_IMM5 = 0x0010, OPN_OFF6 = 0x0020, OPN_VEC8 = 0x0040, OPN_ASC8 = 0x0080, OPN_PCO9 = 0x0100, OPN_PCO11 = 0x0200, OPN_IMM16 = 0x0400, OPN_STR = 0x0800, OPN_FILL = 0x1000 } |
enum | format { FMT_ = 0, FMT_RRR = (OPN_DR | OPN_SR1 | OPN_SR2), FMT_RRI5 = (OPN_DR | OPN_SR1 | OPN_IMM5), FMT_CL = (OPN_CC | OPN_PCO9), FMT_R1 = OPN_DR, FMT_R2 = OPN_SR1, FMT_I11 = OPN_PCO11, FMT_RL = (OPN_DR | OPN_PCO9), FMT_RRI6 = (OPN_DR | OPN_SR1 | OPN_OFF6), FMT_RR = (OPN_DR | OPN_SR1), FMT_V = OPN_VEC8, FMT_A = OPN_ASC8, FMT_16 = OPN_IMM16, FMT_S = OPN_STR, FMT_FILL = OPN_FILL } |
Functions | |
char * | strdup (const char *) |
char | lc3_escaped_char (char c) |
LC3_inst_t * | lc3_get_inst_info (opcode_t opcode) |
inst_format_t * | lc3_get_inst_format (const char *name) |
char * | lc3_get_suffix (char *file_name) |
bool | lc3_file_has_suffix (const char *file_name, const char *suffix) |
char * | lc3_replace_suffix (char *file_name, char *new_suffix) |
const char * | lc3_get_format_name (format_t format) |
const char * | lc3_get_opcode_name (opcode_t op) |
const char * | lc3_get_operand_name (operand_t operand) |
void | lc3_set_obj_file_mode (const char *name) |
int | lc3_read_LC3_word (FILE *f) |
void | lc3_read_sym_table (FILE *sym_file, sym_table_t *symTab) |
void | lc3_write_LC3_word (FILE *f, int value) |
void | lc3_write_sym_table (FILE *sym_file, sym_table_t *symTab) |
bool | lc3_get_address (sym_table_t *symTab, const char *token, int *value) |
This defines the details of the LC3 instruction set architecture (ISA). It is a separate file so that it can be shared by both an assembler and a simulator. It also include various utility routines.
#define LC3_MEM_SIZE (1 << 16) |
The LC3 defines a memory accessed by a 16 bit address
#define LC3_NUM_REGS 8 |
The LC3 contains 8 general purpose register, named R0..R7
#define LC3_VAR extern |
Handy way to define a gloabal variable in header file
#define LC3_WORD unsigned short |
LC3 words are 16 bits
#define RETURN_ADDR_REG 7 |
Return address stored in R7
Define a combinatin of operands an opcode may have. For example, the the LD, LDI, ST and STI instructions all have two parameters. The first is a register, the second is a nine bit offset. This code stores multiple values in a single integer value by using individual bits to encode information. The ordering is right to left, with the rightmost 1 bit being the type of the first operand.
To determine the number of operands an instruction has, simply count the 1 bits in the word. Here is an algorithum by Brian Kernigan, one of the developers of Unix, and co-author of the famous book "The C Programing Language (known as K&R)".
typedef struct inst_format inst_format_t |
This structure stores the information for one form of an instruction. Several instructions have multiple forms, but most have only one.
typedef struct LC3_inst LC3_inst_t |
This structure stores the information about a single instruction. See the usage in lc3.c where the information for each LC3 instruction is defined. The name of the second form will be NULL
unless the instruction actually has two forms.
The LC3 opcodes and pseudo-ops. The codes of OP_BR .. OP_TRAP corresponds exactly to the numeric values assigned to the 16 LC3 instructions. The codes assigned to the pseudo-ops is arbitrary. PCi is the incremented PC
A bit field used to define the types of operands an individual LC3 instruction may have. Each value represents a different bit in the final result. When you see C code like this, it is likely that an integer value is used to represent an "array" of up to 32 values. Each value is accessed with a mask that extracts the bit of interest. See the inst_format_t below.
enum format |
Define a combinatin of operands an opcode may have. For example, the the LD, LDI, ST and STI instructions all have two parameters. The first is a register, the second is a nine bit offset. This code stores multiple values in a single integer value by using individual bits to encode information. The ordering is right to left, with the rightmost 1 bit being the type of the first operand.
To determine the number of operands an instruction has, simply count the 1 bits in the word. Here is an algorithum by Brian Kernigan, one of the developers of Unix, and co-author of the famous book "The C Programing Language (known as K&R)".
enum opcode |
The LC3 opcodes and pseudo-ops. The codes of OP_BR .. OP_TRAP corresponds exactly to the numeric values assigned to the 16 LC3 instructions. The codes assigned to the pseudo-ops is arbitrary. PCi is the incremented PC
enum operand |
A bit field used to define the types of operands an individual LC3 instruction may have. Each value represents a different bit in the final result. When you see C code like this, it is likely that an integer value is used to represent an "array" of up to 32 values. Each value is accessed with a mask that extracts the bit of interest. See the inst_format_t below.
char lc3_escaped_char | ( | char | c | ) |
Convert an escape sequence to a single character
c | the character after the escape character (the back-slash) |
bool lc3_file_has_suffix | ( | const char * | file_name, |
const char * | suffix | ||
) |
Determine if file_name has the specified suffix
file_name | - file name to check |
suffix | - value to match |
bool lc3_get_address | ( | sym_table_t * | symTab, |
const char * | token, | ||
int * | value | ||
) |
Convert a string to an address. The string is assumed to be a symbol. If it is found in the symbol table, the address is returned via the pointer. Otherwise call lc3_get_int() to convert the "number" to an address.
symTab | - the file in which the symbol table is written |
token | - the string to be converted |
value | - pointer to where the address will be stored |
const char* lc3_get_format_name | ( | format_t | format | ) |
Convert a format_t to a "name"
format | - the value to convert (e.g. FMT_RRI5) |
inst_format_t* lc3_get_inst_format | ( | const char * | name | ) |
Get the format for an instructon given its name (e.g. JMP
) The ADD/AND
instructions have two form with the same name and this routine will return the one with three register operands.
name | the opcode as a string (e.g. "JSSR" ) |
NULL
LC3_inst_t* lc3_get_inst_info | ( | opcode_t | opcode | ) |
Get the information for an instruction, given its opcode This is simply an access into an array of values initialized with the information for each of the LC3's sixteen instructions and additional pseudo-ops.
opcode | - the opcode of the instruction/pseudo-op of interest |
const char* lc3_get_opcode_name | ( | opcode_t | op | ) |
convert an opcode_t
to a name
op | - the opcode to convert (e.g. OP_ADD) |
const char* lc3_get_operand_name | ( | operand_t | operand | ) |
convert operand type to a "name"
operand | - the type of operand (e.g. OPN_OFF6) |
convert operand type to a "name"
char* lc3_get_suffix | ( | char * | file_name | ) |
Get the suffix of a file name
file_name | - file name to check |
int lc3_read_LC3_word | ( | FILE * | f | ) |
Read an LC3 word from a file (binary or hex - see lc3_set_obj_file_mode())
f | - the object file |
void lc3_read_sym_table | ( | FILE * | sym_file, |
sym_table_t * | symTab | ||
) |
Read the symbol table file and populate the global variable lc3_sym_tab
. No error checking is performed. It is assumbed the file is in the correct format.
sym_file | the file containing the symbol table |
symTab | pointer to the symbol table |
char* lc3_replace_suffix | ( | char * | file_name, |
char * | new_suffix | ||
) |
Create a new dynamically allocated string with the existing suffix (if any) replaced by a new suffix.
file_name | - original file name |
new_suffix | - replace existing suffix with this value |
void lc3_set_obj_file_mode | ( | const char * | name | ) |
Set 'inHex' depending on the file suffix. lc3_read_LC3_word() and lc3_write_LC3_word() depend on 'inHex'
name | - the name of the file |
void lc3_write_LC3_word | ( | FILE * | f, |
int | value | ||
) |
Write an LC3 word to a file (binary or hex - See lc3_set_obj_file_mode())
f | - the file to write to |
value | - the value to write |
void lc3_write_sym_table | ( | FILE * | sym_file, |
sym_table_t * | symTab | ||
) |
Write the symbol table to a file from the global variable lc3_sym_tab
sym_file | - the file in which the symbol table is written |
symTab | - pointer to the symbol table |
char* strdup | ( | const char * | ) |
Prototype for handy function to duplicate a string. This function allocates dynamic memory and copies the string into that memory. Thus, use of this function implies the need to free the string at some point.