1. Instruction Fetch | |
2. Instruction Decode | |
3. Data Fetch | |
4. Instruction Execute | |
5. Result Return |
The instruction execution simulator is a web page designed to demonstrate the instruction cycle as described in Synder's Fluency 5. The page simulates a simple computer with a very simple instruction set based on the example in Chapter 9. The computer will execute an add instruction similar to the one described in that chapter, and is able to run some small demonstration programs.
The page shows a small memory unit (16 cells) at the left, and a control unit and arithmetic and logic unit (ALU) in the center. On the right is the instruction cycle. Below that is the control panel. The area labeled “Display:” is the computer's output device. The page operate like a real computer: it will repeatedly load the instruction from memory at the location given by the program counter into the instruction register, and execute it. As it does so, the register values in the control unit and CPU will change. Also, the current step in the machine cycle is marked, and the current status is listed in red below the ALU.
The memory, control unit, and ALU all contain storage cells (also called registers). In this machine, each one is 16 bits wide. Click on any one of them to change its value. Register values are binary numbers, but they can be displayed in any number of formats. These are controlled by the buttons under the label “Register Format” in the control area. Press any of the buttons “Decimal,” “Binary,” or “Hex” will cause all registers to be displayed in base ten, base two, or base sixteen. The “Instruction” button will cause each cell to be interpreted as a machine instruction. All instructions are represented as 16-bit numbers, and any such number can be interpreted as an instruction. The button labeled Guess (which is also the default setting) guesses an appropriate format for each register. Since any 16-bit value could be displayed any of these ways, the guess button may not always choose well.
You might want to experiment with different format settings to see what they look like, though if you just opened the page, all the registers are zero. Remember, though: None of the Register Format buttons changes the value of any register, just the way it is displayed. That also means they're safe to press any time. Experiment with these when you get a chance.
When the Instruction Execution page loads, the memory is empty. You can always enter information into cells directly, but it's usually easier to use one of the provided programs. Use the “Load Program” drop-down to load one into memory. These programs are available:
Simple Sum | This is a very simple program which runs an add instruction to add 45 and 81. It then displays the sum in the output area. |
Input and Sum | This program reads two numbers from the user, and places their sum in the output area. |
Counter | A loop which counts to ten. |
Shifter | Uses binary operations to generate a the binary numbers of all ones: 1, 11, 111, etc, up to 16 ones. |
The step button makes the machine run one step then immediately pause. It is useful to study the operation of each instruction in detail. You can step through the instruction as slowly as you need to see all the register changes. The page displays a message about what the machine is doing below the ALU. For each step in the machine cycle, it first describes what it will do, then performs the operation and describes what just happened. Each of the five steps requires two label displays, so there are a total of ten messages for each instruction. If you are using the step button, you must press it for each of these ten operations.
First, load the simple add program, and let the machine run it to see how it runs. Then press reset to start over, and use the step button to go through the program slowly and observe the effects of each instruction. (Each machine instruction does just a small bit of work; real programs must run millions or billions of them.)
Once you have had a chance to see the simple program works, and how to run the machine, load some of the other programs and play with them. You migh try modifying one of the programs to get different behavior, or tweak one of the registers to see what happens.
You may also create programs of your own. The simulator is simple and limited, but can do more than the small list of given programs. In this case, you might want to look at the instruction set reference.
This page lists the instructions supported by the CPU simulator.
The information on this page is not part of the CSc 114 course, and will not be on any exam. It's here for anyone interested in learning a little more about the simple processor the instruction cycle page emulates. It describes the instructions the CPU understands, in both assembler and binary formats.
There are 16 instruction types. Each can be coded as a 16-bit binary number for storage in cells or registers, or shown in assembly form for human consumption. For instance, the instruction given as add 5,9,12 in assembler is coded as the binary number 0001 0101 1001 1100. You may change any register or memory cell value by clicking there and entering what you like. To enter an instruction, you may give it either numerically or in assembler. You may display the values in either form using register format control buttons on the Instruction Execution page.
The table below gives assembly and binary for each instruction type. Most have four four-bit parts (called fields), though some have two four-bit ones and an eight-bit. The first field is the operation code, and the others specify the operands. Most operands specify a memory address where a value is located, but the 8-bit operands give values directly. Some instructions don't need all their operands, and ignore the extra fields. Ignored fields are shown as xxxx in the formats below, since any value may be placed there. For example, add 12,5,9 sets res to 12, a1 to 5 and a2 to 9. To code in binary, you must convert each operand to binary, expand it to four bits, and put it in place. Since 12 is 1100 in binary, 5 is 0101 and 9 is 1001, we can code the add by starting with its op code, 0001, then filling in the operands to get 0001 1100 0101 1001. Again, not 5,3 can be coded as 0101 0101 0011 0000, with the xxxx area set to zero.
These are the instruction types which the execution page understands.
Assembler | Coding | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
nop | 0000 | xxxx | xxxx | xxxx | ||||||||||||||||||||||
The nop instruction stands for “no operation,” and it does nothing. The three argument positions are ignored, so any cell starting with four zero bits is a nop instruction. | ||||||||||||||||||||||||||
add res, a1, a2 | 0001 | res | a1 | a2 | ||||||||||||||||||||||
Adds the contents of the memory location given by a1 to the memory contents at a2 and stores the result in the address given by res. | ||||||||||||||||||||||||||
sub res, a1, a2 | 0010 | res | a1 | a2 | ||||||||||||||||||||||
Same, but subtracts the contents of memory at a2 from the value stored at a1. | ||||||||||||||||||||||||||
and res, a1, a2 | 0011 | res | a1 | a2 | ||||||||||||||||||||||
Performs a bitwise and of the number at memory location a1 with the one at a2 and stores the result in location res. A bitwise and operates on pairs of bits in the same position in the two operands, placing a 1 in the result when both operands have a 1, and a 0 otherwise. For instance, 11011010 and 01100010 produces 01000010. | ||||||||||||||||||||||||||
or res, a1, a2 | 0100 | res | a1 | a2 | ||||||||||||||||||||||
Same, but performs a bitwise or of a1 and a2. Or produces a 1 in the result where there is a 1 in either operand. For instance, 11011010 or 01100010 produces 11111010. | ||||||||||||||||||||||||||
not res, a | 0101 | res | a | xxxx | ||||||||||||||||||||||
This computes the bitwise inverse of the value in the memory location given by a and stores it in the address given by res. The bitwise inverse is simply the value with the opposite bit in each position. For instance, the inverse of 11011010 is 00100101. | ||||||||||||||||||||||||||
sti res, c | 0110 | res | c | |||||||||||||||||||||||
In this instruction, c is an actual data value, not the address of a data value. The sti instruction stores this constant value in the memory location given by res. Since the memory location is longer than the constant (16 bits instead of 8), the CPU expands the constant by repeating the left-most bit 8 times and adding these 8 bits to the front the the number. The reason for this rule is so the CPU can use two's complement to represent negative numbers, and this is the correct way to expand the size. | ||||||||||||||||||||||||||
stih res, c | 0111 | res | c | |||||||||||||||||||||||
This is very similar, except the constant is stored in the left (most-significant) half of the memory location given by res. Since the size of the constant is half the size of the memory cell, no expansion is needed. For instance, if cell 10 contains 1011 1100 0101 1101, then stih 138,10 would change it to 1000 1010 0101 1101. The purpose of this instruction is that it allows a program to store a full 16-bit number by using an sti followed by an stih. | ||||||||||||||||||||||||||
addi c, res | 1000 | res | c | |||||||||||||||||||||||
This instruction adds the constant c to the value stored in memory location res, and returns the sum to location res in memory. Before the addition is performed, c is expanded to 16 bits by repeating the sign bit as in the sti instruction. | ||||||||||||||||||||||||||
shft res, c | 1001 | res | c | |||||||||||||||||||||||
This instruction takes the value in memory location res and shifts it left by c, where c treated as a two's complement signed value. If c is negative, the shift is a logical right shift. A shift means the bits are moved over, left or right, with the extra space filled with zeros. For instance, 1101 0001 1100 1001 shifted left three places is 1000 1110 0100 1000. Shifted right five places (a shift count of -5) instead would give 0000 0110 1000 1110. | ||||||||||||||||||||||||||
jmp targ | 1010 | targ | xxxx | xxxx | ||||||||||||||||||||||
Unconditionally jump to the memory location given by targ. The effect of this instruction is to copy targ to the pc register (and fill it out with zeros on the left). That way, the next instruction executed will be the one in that location, and execution will then continue from that place. This instruction can be used to jump forward to skip instructions, or (more often) to jump backwards to create a loop (repetition). In either case, it is most often used in conjunction with one or more of the conditional jumps below. Conditional jumps allow a loop to exit when some condition indicates that it is time to stop. | ||||||||||||||||||||||||||
jlt targ, a1, a2 | 1011 | targ | a1 | a2 | ||||||||||||||||||||||
See if the value stored in memory location a1 is strictly less than the value stored in a2. If true, then jump to targ just as the jmp instruction does. If not true, do nothing. In the later case, the next instruction to execute will be the one following, as usual. When the comparison is made, the values are treated as signed values under 16-bit two's complement notation. | ||||||||||||||||||||||||||
jeq targ, a1, a2 | 1100 | targ | a1 | a2 | ||||||||||||||||||||||
This is the same as jlt, except the values are compared for equality. If the value in memory location a1 equals the value stored at a2, copy targ into the pc. Otherwise, do nothing. | ||||||||||||||||||||||||||
disp type, a | 1101 | xxxx | type | a | ||||||||||||||||||||||
This is the output instruction, and it causes the contents of memory
location a to be displayed in the output area using the format
specified by type. The legal format types and meanings are
listed below. Each line gives the symbol to write in assembler, and
the value of the type field in the binary coding.
| ||||||||||||||||||||||||||
in dest, type | 1110 | dest | type | xxxx | ||||||||||||||||||||||
This is the input instruction. It will pop up an entry window and ask the user for a value, which will be placed into memory at address dest. The type field gives the format required for the input value, and is one of bin, dec, hex or chr listed under the disp instruction. (clr and app are not allowed on input.) | ||||||||||||||||||||||||||
halt | 1111 | xxxx | xxxx | xxxx | ||||||||||||||||||||||
Halt the CPU. It will stop executing instructions, but all registers remain unchanged. Executing halt is very similar to pushing the PAUSE button on the execution control console, except the next press of START will automatically reset the machine before starting it running. (Pressing START after PAUSE simply resumes execution without a reset.) |
Note that the xxxx fields are usually coded with zeros, but can contain any value, since the CPU is going to ignore them anyway. When you enter an assembly instruction into a register, the execution page will use zeros, so not 5,3 will be coded 0100 0101 0011 0000 as shown above. But 0100 0101 0011 1011 would also be valid. Any 16-bit number starting with four ones is a valid halt. If it starts with four zeros, it's a nop.