Imaginary Computer

Representing Program Instructions

Imaginary Computer Design
Imaginary Computer Instructions
Imaginary Computer Instruction Set
Program 1: Add 2 Numbers
Program 2: Simple Loop
Imaginary Machine Simulator

Imaginary Computer Design

The Imaginary Computer is a conceptual computer that simulates many of the basic features found in modern electronic digital computers. It is designed to demonstrate the "Stored Program Computer Architecture," also known as "von Neumann Architecture," named for the mathematician John von Neumann (1903-1957, pronounced noy mahn).

Imaginary Computer
Imaginary Computer

The Imaginary Computer is made up of the following main parts:

[ TOP ]

Imaginary Computer Instructions

An Imaginary Computer instruction is 8 bits wide and has 2 parts:

The Imaginary Computer has 2 instructions for calculations: ADD and SUB for addition and subtraction respectively. In both cases the operand specifies the memory address of the data to be added or subtracted. The operation is performed on whatever is currently in the accumulator, and the result is stored in the accumulator.

3 instructions manage data. LOD copies the data item from the memory address specified by the operand and "loads" it into the accumulator (the contents of memory are not changed). LDC Loads the constant specified in the operand into the accumulator. Note that while the accumulator can hold an 8-bit value, operands are limited to 5 bits; therefore, to allow for positive and negative constant values, the range of constant integers that can be loaded with LDC from -16 to + 15. STO copies the contents of the accumulator to the memory address specified in the operand.

Note ADD, SUB, LOD, and LDC above: the contents of the accumulator are very temporary; any useful work in a computer requires constant storing of data in memory to save intermediate results and constant loading data from memory to perform calculations.

3 instructions control the program flow. The control unit fetches the instruction located at the memory address specified by the Program Counter, stores it in the Instruction Register, decodes and executes the instruction (using the ALU and registers), then increments the Program Counter. Having completed the cycle, the PC is pointing to the next instruction and the control unit is ready to start again. This is called sequential program flow and is a lot like a mail carrier walking down the street and delivering mail to each house in order.

Frequently we want to do the same (or similar) operations over and over. The Imaginary Computer uses the JMZ instruction to set the Program Counter to the value specified in the operand if the accumulator is 0; the JMP instruction sets the Program Counter to the value specified in the operand if the accumulator is equal or greater than 0 (e.g. is positive).

Finally, and perhaps most important of all, we need to tell the computer when to stop with the HLT instruction. If we did not have a way to tell when to stop, the Control Unit would just continue to faithfully fetch instructions. Eventually it would get down into our data area and try to decode and execute those values as if they were instructions, possibly with disastrous results.

[ TOP ]

Imaginary Computer Instruction Set

Opcode Description
Binary Mnemonic
  000   HLT Halt execution of the program.
  001   LOD Load a copy of the value in the referenced memory location in the accumulator.
  010   LDC Load the constant value of the operand in the accumulator.
Note: limited to 5 bits (-16 to +15)
  011   STO Store a copy of the contents of the accumulator in the referenced memory location.
Note: the value in the accumulator does not change
  100   ADD Add the value in the referenced memory location to the value in the accumulator; store result in the accumulator.
  101   SUB Subtract the value in the referenced memory location from the value in the accumulator; store result in the accumulator.
  110   JMP Jump to the referenced memory location if the value of the accumulator is a positive number (equal or greater than 0).
  111   JMZ Jump to the referenced memory location if the value of the accumulator is 0.

[ TOP ]

PROGRAM 1

The following Imaginary Computer program adds 2 numbers that are loaded in the accumulator via the LDC instruction, assigning the first number to memory location 30 and the result to memory location 31. Note that the program starts reading instructions at memory address 0 and continues sequentially until the HLT instruction is executed.

Machine Language
Address: Instruction
00: 01000101
01: 01111110
02: 01001101
03: 10011110
04: 01111111
05: 00000000
 
Assembly Language
Address  Instruction
00  LDC 5  ;load constant 5 in AC
01  STO 30 ;store AC value in [30]
02  LDC 13 ;load constant 13 in AC
03  ADD 30 ;add value in [30] to AC
04  STO 31 ;store result in [31]
05  HLT    ;halt program execution

Try "running" this program on paper using only the Machine Language version (the one in binary). Assume that the Program Counter always starts at 00 and the Accumulator is 0 and program startup.

Now look at the Assembly Language version. While machine language is the only language the computer understands at the CPU level, assembly language is much easier for humans to read and understand.

[ TOP ]

PROGRAM 2:

        DEF 31 0            ;loop counter, init to 0
        DEF 30 4            ;number of repetitions
                            ; Start of program
                            ; LOOP
        LOD 30              ;00 AC = num reps
        SUB 31              ;01 0 when counter = limit
        JMZ 07              ;02 goto END LOOP if 0
        LDC 1               ;03 increment by 1
        ADD 31              ;04 increment counter
        STO 31              ;05 save counter
        JMP 00              ;06 goto LOOP
                            ; END LOOP
        HLT                 ;07
A program called an assembler translates the above symbolic mnemonic instructions into the binary memory image below. The symbols LOD, ADD, etc. mean nothing to the computer and the processor; when the assembler is finished they are not anywhere in memory.
        00:00111110         ; LOD 30
        01:10111111         ; SUB 31
        02:11100111         ; JMZ 07
        03:01000001         ; LDC 1
        04:10011111         ; ADD 31
        05:01111111         ; STO 31
        06:11000000         ; JMP 00
        07:00000000         ; HLT
         .    .             ;
         .    .             ; additional unused memory
         .    .             ;
        30:00000100         ; pre-loaded to 4
        31:00000000         ; pre-loaded to 0

This program subtracts a counter (starting at 0) from a known value (4) that we want to count up to, then uses the JMZ instruction to compare the result in the accumulator with 0 (this is the Logic part of the ALU). If the accumulator is not 0, the instruction is ignored and program control proceeds to the next instruction.

Next we add 1 to the counter and save the new value. The JMP instruction jumps to the address specified in the operand if the accumulator is positive (equal or greater than 0); this is guaranteed to jump because we just explicitly performed the addition of our counter.
(Note: If we counted far enough, eventually the counter would "overflow" and become a negative number, causing the jump to fail. In this case the next instruction would be executed, which is HLT.)

The program ultimately halts when the counter gets up to 4: the result of the subtraction is 0, JMZ finally has the condition it needs to jump to the address in its operand, which is the location of the HLT instruction.

Note the implication of forgetting to store the value of the counter back in memory after incrementing the counter: the counter keeps getting loaded as 0, the result of the subtraction is always 4, and the accumulator never decrements to 0. This is called an infinite loop.

The following table shows a "program trace" for each pass through the loop until the JMZ instructions finds 0 in the accumulator the program stops. The * character is used to show that the program did not execute the instruction on that pass due to branching by the JMZ or JMP instruction.

Address Instruction/Directive Accum Accum Accum Accum Accum
00 LOD 30 4 4 4 4 4
01 SUB 31 4 3 2 1 0
02JMZ 07 4 3 2 1 0
03LDC 1 1 1 1 1 1
04ADD 31 1 2 3 4 *
05STO 31 1 2 3 4 *
06JMP 00 1 2 3 4 *
07HLT * * * * 0
  Data Area
30DEF 30 4 4 4 4 4 4
31DEF 31 0 0 1 2 3 4
[ TOP ]

Imaginary Computer Machine Simulator

Imaginary Computer Machine Simulator

While the Imaginary Computer is designed to be used with pencil and paper, it is also valuable to watch the instructions in action and to verify if your programs work.

I have written an Imaginary Computer simulator in JavaScript where you can enter and try programs and see the results. You can enter binary machine instructions directly in the memory cells or you can type assembly instructions in the Assembly window, assemble them, then load them into memory.

Note that the simulator is a "work in progress," if you find errors or discover something that does not work please let me know.

[ TOP ]