logic.c
. You will be reusing the file(s) fields.c
and/or symbol.c
you wrote for previous assignment(s).
You will likely add many functions to the code that has been provided to you. However, most of them are should be very short (2 to 3 lines). The reference implementation of this code contained less than 300 lines. The complexity lies in understanding the pieces and how they fit together.
cd
there.lc3sim.XXX.tar
file. This will create a subdirectory
lc3SIM
containing all of the files for the project.
tar -xvpf lc3sim.XXX.tar
cd lc3SIM
and do all your work in that directoryfield.c
by your version. In lieu of this, you
may simply write code for the necessary functions. (equivalent of
getBit()
and getField()
) in your
logic.c
file.symbol.c
by your version.Makefile
and make sure the variable GCC
is appropriate for your C compiler. Also, verify that sed
in in your $PATH
. This will be OK for the department linux
machines.install.c.MASTER
and
mysim-tk.MASTER
and look for the string
abs_path_to_install_dir
. It occurs once in each file.
./fixPath install.c mysim-tk
Examine the files install.c
and mysim-tk
and
verify the string has been replaced by the path to this directory.
This script uses sed
and will not work if it is not in your
$PATH
or is not available. In this case, you may use an
editor to update the files.mysim
make
You should see the following on linux (the warning about write_DR is expected).
gcc -g -std=c11 -Wall -c -DSTACK_OPS -DDEBUG Debug.c gcc -g -std=c11 -Wall -c -DSTACK_OPS -DDEBUG field.c gcc -g -std=c11 -Wall -c -DSTACK_OPS -DDEBUG install.c gcc -g -std=c11 -Wall -c -DSTACK_OPS -DDEBUG logic.c logic.c:31:13: warning: ‘write_DR’ defined but not used [-Wunused-function] static void write_DR (instruction_t* inst, LC3_WORD value) { ^~~~~~~~ gcc -g -std=c11 -Wall -c -DSTACK_OPS -DDEBUG symbol.c gcc -g -std=c11 -Wall Debug.o field.o install.o logic.o symbol.o lc3simPA.a -o mysim
./mysim-tk -norun
or
./mysim -norun
if you prefer the command line version.0x200
. The is the LC-3 operating
system code. Note that you see labels, but NO code. What is
happening is that the main program is loading the object code for the LC-3
operating system and storing it in memory by calling
logic_write_memory()
. Because you have not yet implemented
this function, nothing is actually stored in memory!logic_write_reg()
, but you
have not implemented this yet.logic.c
. However, if
the functions of symbol.c
are not correct, you may need to revisit
them.
The first thing you need to do is to implement
logic_write_memory()
and logic_write_reg()
. Study
the code for logic_read_reg()
and
logic_read_memory()
and the functions documented in
hardware.h
. Review all the provided source code and plan
what you need to do before writing code. You will NEED to use the
functions in hardware.h
and definitions in logic.h
.
When you are prepared, do the following:
logic_write_reg()
and
logic_write_memory()
.make
and re-build your simulator../mysim-tk -norun
or
./mysim -norun
..0x200
.logic_fetch_instruction()
logic_fetch_instruction()
logic_decode_instruction()
logic_execute_instruction()
You will complete the first function and then work incrementally on the other two to complete your assignment.
The function logic_fetch_instruction()
is quite similar to the
function logic_read_memory()
, but the value needs to end
up in the instruction register (IR). Look at the functions documented in
hardware.h
. Also read the documentation of this function to see
what else it must do.
To test this, use the very simple LC-3 program:
.ORIG x3000
ADD R0,R1,R2
HALT
.END
Create the program with an editor and assemble it using lc3as
. You
can now test whether your implementation works. To test it, do the following:
make
to rebuild the simulator.-norun
).logic_fetch_instruction()
is correct, you will see the
ADD
instruction in the IR.ADD
instructionADD
instruction work. This involves
adding code to both logic_decode_instruction()
and
execute_ADD()
.
Looking at the code for
logic_execute_instruction()
, note that the switch
is
based on the field opcode
. This implies that the function
logic_decode_instruction()
MUST set that field at a minimum.
In setting the fields of this data structure, you will need to write C code
involving shifting and masking to extract the values from the 16 bit instruction.
Look at the simple LC-3 program above and figure out what additional pieces of
information the instruction will require. Add code to
logic_decode_instruction()
to determine those values. Note that in
this program, no immediate value is used, so you can delay implementing that
portion of the code. If you wrote the assembler programming project, you
will find that the logic_decode_instruction()
is essentially doing
the inverse of what pass_two()
did.
At this point, you are going to take a little detour to make
completing the code
for execute_ADD()
easier. Look at the function
write_DR()
. Many methods write to a destination register.
So, if you decide to
implement this method, it will prove useful for other instructions as well.
As its
name implies, the function stores a value in a register.
It does one other thing.
Look at the LC-3 ISA operation descriptions in appendix A in the book
and determine what else every store
into a register does. Add
code for this operation. Alternatively, you can delay writing code for this
second operation. It will not be needed until you work on BR
.
Now return to the execute_ADD()
function. The ADD
instruction adds two values and stores the result in a register. The two values
come from SR1OUT
and the SR2MUX
. These values can
be filled in during logic_decode_instruction()
. Note that
SR2MUX
is an array of two values. Think about how bit5
is defined and how it might be used as an index into SR2MUX
.
In summary:
logic_decode_instruction()
to get the
opcode
.logic_decode_instruction()
to get the
register values needed for ADD
.write_DR()
. inst_fields
struct (see its comments), you may wish to add code to logic_decode_instruction()
to get the
SR1OUT
and SR2MUX[0]
values.execute_ADD()
to do the add and store the
value. Make sure the function returns OK
.make
and fix any problems.ADD
instruction, you will need to
handle immediate
values. This requires only a very small change in decoding and execution. Make
those changes and test it with another simple test program.
Congratulations, you are done with one instruction. You are really a lot
further along that that. You should be able to finish the AND
and
NOT
instructions with minimal effort. And you have a nice utility
routine that will be used elsewhere as well.
The computation of the effective address will use the ADDR1MUX
and
ADDR2MUX
. Look at the documentation for the data structure
inst_fields
under the data structures tab of the assignment webpage..
The MUXs are modeled as arrays.
MUXs do not actually store anything, but simply take multiple inputs and select one
of the inputs as the output, depending on the select lines. In this model,
the array holds the inputs and the select is actually an index into the array.
The array values are set as part of logic_decode_instruction()
and
used in logic_MARMUX()
.
You will now implement code for decoding/executing a single LC-3 instruction at a time. The following sequence may be useful:
LD
).logic_decode_instruction()
to set these values
in the data structure inst_fields
.logic_MARMUX()
to handle this
instruction.For this assignment, you can assume that all input programs are correct in the following ways:
TEST! TEST! TEST! Once you are happy, execute the simulator without the
-norun
. The OS will now load and print out the welcome message.
This is a good test of your work because many (but not all) of the LC-3
instructions are used in the OS. You can also set up regression tests
that compare the output of ~cs270/lc3tools/lc3sim with mysim.
You may find it useful to run your simulator and the class simulator (from ~cs270/lc3tools) side by side and single step both of them and compare what you see.
If you like to do debugging with printf()
, you may do so, but you
will NOT be able to use the GUI version of the simulator. This is
because printf()
is used to to send data from the simulator to
the GUI and your printf()
may cause the GUI to die.
The command line version of the simulator (mysim
) has no
problems with additional output. However, grading WILL be affected,
so you must turn off any degugging in the code you submit!
Even though you do not have all the source code, you may use gdb for debugging.
If you are comfortable with the console lc3 simulator, you may use gdb as you were shown in earlier recitations. Simply do the following:
gdb mysim
logic.c
. This is the only file you are modifying for this
assignment. The general gdb syntax is break functionName
run -norun
This start the lc3 simulator, but does not
execute any LC3 code. The lc3 simulator program is running, but will halt
at any mysim breakpoints you have set.continue
to return control to the LC3 console.If you prefer the GUI version of the lc3 simulator, you may still use gdb but you will need to do several additional steps.
mysim-tk
).
ps -fu yourLogin | grep mysim
and you will see several processes listed. One will be the grep
,
one will be the mysim-tk
and the third will be the actual
simulator mysim
. The process ID will be the first number on the
line.logic.c
. This is the only file you are modifying for this
assignment. The general gdb syntax is break functionName
continue
This resumes the lc3 simulator.continue
to return control to the LC3 GUI.mysim.tar
using the
checkin
program or the Checkin tab of the web page.This file
may created by executing make submission
.
type:
~cs270/bin/checkin LC3SIM mysim.tar
Relax, you are done with your assignment! The semester is almost over. :)