THE ORGANIZATION AND PROGRAMMING OF A SIMPLE COMPUTER

Richard R. Eckert
THE VON NEUMANN STORED-PROGRAM COMPUTER (Fig. 1)

Most digital computers follow John Von Neumann's classical, stored-program model in
their internal organization. In this model the computer is composed of the following 
functional parts: the central processing unit (CPU), the memory, and one or more 
input-output (I/O) units.
The CPU performs two basic functions:

(1) It controls and coordinates the activities of the other parts of the computer
and of its own  component parts. This control function is performed by circuits 
which send out sequences of control signals that cause the various components of 
the computer to act at the correct times.

(2) It processes information that it contains or that is sent to it by the other 
units. This processing function is carried out by circuits capable of performing 
arithmetic and logical operations on data contained within the CPU.

The memory of a digital computer may be visualized as a series of compartments or 
cells, each of which can hold one binary number. Each cell has another number 
associated with it (called its address) that uniquely identifies which cell it is. 
The addresses of a given memory normally range from zero up to an integer that is 
one less than the capacity of the memory. The number stored within a given cell is 
called a word, and a stored word may be data that can be manipulated by the CPU or 
a code number representing an instruction that can be executed by the CPU. A 
sequence of coded instructions stored in memory that, when executed by the CPU, 
causes some specific task to be performed is known as a computer program.

Input and output units provide communication between the computer and the external 
world of continuously-varying (analog) signals.  These signals are unintelligible 
to the digital circuits within the computer, which respond only to discrete (1 or 0) 
signals.  Input units convert analog signals from external world devices to the 
digital signals used inside the computer. Output units perform the inverse function. 
In most cases input and output devices are electro-mechanical in nature and much 
slower than the computer's CPU or its memory. Therefore an interface is needed to 
coordinate the transfer of data between the CPU and the I/O device. Such an 
interface is often called a port, and, as in the case of memory, each port may have 
a unique identifying address.

BASIC CYCLE OF OPERATION (FETCH-DECODE-EXECUTE)

All of the operations that occur within a digital computer are synchronized by a 
common clock that provides a regular stream of pulses. These pulses provide a time 
base for the basic fetch-decode-execute cycle that occurs inside the machine. 
During the fetch part of the cycle, the next coded instruction is brought into the 
CPU from memory. Decoder circuits then determine what the instruction is, sequencer 
circuits, in turn, output the appropriate series of control signals to cause the 
instruction to be executed. This latter phase is known as the execute part of the 
cycle. The basic fetch-decode-execute cycle is repeated continuously until the 
clock is stopped.

CONNECTING THE COMPONENTS--THREE BUS ARCHITECTURE (Fig. 2)

A "bus" is a common signal path that can be used for communication between pairs of 
receivers and transmitters selected from many (tens of thousands to millions of) 
possible candidates. Many digital computers have three-bus architectures in which 
the transfer of information between component parts requires three communication 
paths: an address bus, a data bus, and a control bus.


The address bus carries the address of the next piece of data to be transferred 
between the CPU and the memory or I/O units; the data bus carries the actual data 
to be transferred, and the control bus carries control signals from the CPU to 
memory and I/O units. Important control signals are: MEMR, which, when active, 
causes the data contained in the memory cell whose address is currently on the 
address bus to be placed on the data bus; MEMW which, when active, causes the 
information currently carried on the data bus to be stored into the memory cell 
whose address is on the address bus, IOR, which is like MEMR, except that the 
address is that of an input port; IOW, which is like MEMW, except that the 
address is that of an output port.

A SIMPLE (FICTITIOUS) CPU (Fig. 3)

To illustrate the internal organization, functioning, and programming of a digital 
computer, we now present a fictitious computer system. The CPU of this computer is 
about as simple as could be imagined. Its CONTROL SECTION contains a Program 
Counter (PC) register (sometimes called an instruction pointer) which always holds 
the memory address from which the next instruction is to be fetched. An Instruction 
Register (IR) receives each instruction as it comes in from memory. Decoder and 
controller/sequencer circuits output the correct series of control signals 
necessary to execute the instruction contained in the IR.

The PROCESSING SECTION of the CPU contains an arithmetic-logic unit (ALU), which can 
perform operations on data contained in its two input registers: the accumulator 
(ACC) and register B. This very simple ALU is capable only of adding or subtracting. 
The ADD and SUBTRACT signals are provided by the CONTROL SECTION of the CPU. For 
each of these two functions, the ACC will contain the result of the operation 
after execution.
INSTRUCTION FORMATS (FICTITIOUS) FOR THE SIMPLE PROCESSOR

Instructions for this machine are three digits long. The first digit (op-code field) 
specifies a code (0-9) for some basic instruction in the set of instructions that 
the machine can perform. The second two digits (operand field) specify an address 
(memory or I/O). For each type of instruction, the word contained in the memory cell 
or I/O port specified by the address contained in the operand field will be 
manipulated by the CPU. The op-code field specifies WHAT is to be done; the operand 
field specifies WHERE the data to be operated on is located.

OPCODE  OPERAND
 __________________
/_____/_____/_____/     <----- A 3-digit instruction


A SAMPLE ( FICTITIOUS) INSTRUCTION SET

The following table presents a set of instructions that may be executed on our 
fictitious computer. For each, the op-code number, a memory-aiding "mnemonic", and 
a description on what the instruction does are specified.

OPCODE  MNEMONIC   MEANING
-------------------------------------------------------------------------------------
0       NOP        No operation occurs.

1       LDA        The data word contained in the memory address specified in the
                   operand field of the instruction is copied into the ACC register.

2       STA        Data in the ACC is copied to the memory cell whose address is
                   contained in the instructions operand field.

3       ADD        The word contained in the memory cell whose address is specified
                   in the operand field is added to the contents of the ACC; 
                   the result replaces the former contents of the ACC.

4       SUB        The word contained in the memory address specified in the operand
                   field is subtracted from the ACC; the result replaces the former
                   contents of the ACC.

5       IN         Data contained in the input port whose address is given in the
                   operand field is copied to the ACC.

6       OUT        Data in the ACC is copied to the output port whose address is
                   contained in the operand field.

7       JMP        Fetch the next instruction from the memory address contained in
                   the operand field (unconditional jump).

8       JN         The next instruction is to be fetched from the address in the
                   operand field if the ACC contains a negative number (conditional
                   jump).

9       HLT        Clock stops.


INSTRUCTION CODING

(A) MACHINE CODE (machine readable and executable)

As mentioned above, for our simple computer, each instruction is one three-digit 
number. The first digit expresses the opcode and the second the operand. (In 
reality the digital circuits within the CPU would receive these numbers in binary 
(1 or 0) form so that they could react by opening or closing the proper switches, 
thereby causing the correct actions to occur.) Some examples of machine language 
instructions for our fictitious machine follow:

Instruction     Meaning
------------------------------------------------------------------------------------
154             load the ACC from memory location 54

376             add to the ACC the contents of location 76

582             load the ACC with the word provided by the input device connected to
                port 82

712             fetch the next instruction from location 12

900             stop the clock (the 00 is arbitrary)

(B) ASSEMBLY LANGUAGE CODE (symbolic, non-machine-executable)


Since it is difficult to program in machine language, symbolic "assembly" languages 
have been devised in which there is a one-to-one correspondence between instructions 
written in these languages and their machine language counterparts. Both the 
machine language for a given computer and its associated assembly language are 
machine specific; they may not be used on computers with a different internal 
organization.

An assembly language program consists of a sequence of assembly language statements. 
Each statement can be any of the following:

1. Instructions written in mnemonic form. There is a one-to-one correspondence 
between an assembly language instruction and the corresponding machine language 
instruction. A program called an "assembler" is usually used to translate assembly 
language instructions to their machine language counterparts.

2. Pseudo-ops. These statements are called pseudo-ops since they generate no machine 
language code. There are two general types:

  A. Data allocation pseudo-ops. These define data to be used; Memory space will be 
reserved to hold the data. These are like variables in a high-level language. Names 
can be given to the memory space allocated. An example is the DW (define word) 
pseudo-op.

  B. Assembler directives. These are statements that provide information to the 
assembler program. Examples are: END--end of program; ORG--change the current 
address; EQU--assign a value to a symbol (define a constant).

3. Macro definitions. A macro is a single statement that stands for a block of 
statements. We'll look at macros later in the course.

Assembly language instructions have four fields:

1. An optional name field. This is a symbol that can be referenced by other 
statements. The assembler usually assigns the value of the current memory address 
to this symbol. The current address is kept track of by an assembler variable 
called the location counter.

2. The operation field. This is a mnemonic that represents the opcode (for an 
instruction) or the pseudo-op (for data allocation or assembler directives). This 
field is always present.

3. The operand field. This field contains information that specifies what is to be 
operated on (the object of the operation). It is almost always present.
        
4. An optional comment field. This is used for documentation purposes. Since, in 
general, assembly language instructions are so primitive, assembly language 
programs tend to be long and very obtuse. It is therefore very important that the 
comment field be used so that the reader of the program understands what each 
statement in an assembly language program is doing.

Most assemblers require that a statement be placed on a single line with the 
various fields separated by white space (one or more blanks or tab characters).


AN EXAMPLE ASSEMBLY LANGUAGE PROGRAM

The following assembly language program is targeted for our simple computer. It 
makes use of several pseudo-ops  mentioned above and mnemonics given above for 
the various opcodes in the instruction set of our machine. It computes the sum 
of the two numbers stored in memory locations 07 and 08 and then outputs the 
result to port 04. (Microsoft MASM and Borland TASM assembler conventions have 
been used.)

Name field  Operation field  Operand field  Comment field
-------------------------------------------------------------------------------------
;*** A program to add two numbers stored in memory and output the result ***

;*** First constants and data definitions ***
OPORT       EQU              04             ;OPORT stands for 04
            ORG              07             ;Set  location counter to start of data
NUM1        DW               53             ;Assign value 53 to NUM1
NUM2        DW               41             ;Assign value 41 to NUM2

;*** Now the instructions ***
            ORG              00             ;First instruction stored at address 0
            LDA              NUM1           ;Get first number
            ADD              NUM2           ;Add second number
            OUT              OPORT          ;Output result
            HLT                             ;Stop computer's clock
            END                             ;Tell assembler program is done


ASSEMBLING THE PROGRAM

Most assemblers are two-pass assemblers. During pass 1 internal opcode tables are 
used to translate the mnemonics to their machine language opcodes. In addition any 
symbols appearing in the name field are placed in a symbol table along with their 
"values." In the case of data definition pseudo-ops like DW, the value is the 
current address (location counter). During pass 2 the any unresolved symbols are 
retrieved from the symbol table. (See the second example below.)

Most assemblers will produce a human-readable file that shows both the machine 
language and the assembly language. The format is usually as follows:

MACHINE LANGUAGE                  ASSEMBLY LANGUAGE
address   contents                name   operation   operand   comment

For the simple adding program above, this file would look like the following (The 
comment field has been left blank):

MACHINE LANGUAGE                ASSEMBLY LANGUAGE
address         contents                name            operation       operand
---------------------------------------------------------------------------------
                                        OPORT           EQU             04
07                                                      ORG             07                      
07              053                     NUM1            DW              53
08              041                     NUM2            DW              41
00                                                      ORG             00
00              107                                     LDA             NUM1
01              308                                     ADD             NUM2
02              604                                     OUT             OPORT
03              900                                     HLT
                                                        END

The symbol table would look like the following:

Symbol  Value
-----------------------------------------------------------------------------------
OPORT   04   ;note that for equates the value of the symbol is in the operand field
NUM1    07   ;for DWs the value of the symbol is the current location counter value
NUM2    08

In this very simple program, nothing was done during assembler pass 2, since all 
symbols were in the symbol table at the time they were referenced.

For our simple machine each instruction is exactly one word long. The assembler 
automatically increments the location counter for all instructions and DWs. In a 
real machine like the Intel processors, this is not the case. Instructions can be 
from 1 to 7 bytes long!


WHAT HAPPENS DURING THE FETCH CYCLE

-1st clock pulse: The contents of the PC are placed onto the address bus.

-2nd clock pulse: The MEMR line of the control bus is activated.  This causes memory 
to respond by placing the data contained in the location whose address is on the 
address bus onto the data bus.

-3rd clock pulse: The IR receives the data that is on the data bus.  At the same 
time the PC is  incremented.  The instruction is now safely in the IR, where it can 
be decoded; The PC points to the next instruction in memory. The execute portion of 
the cycle will now occur.  What happens next depends upon what the instruction is.


THE EXECUTE CYCLE OF SEVERAL INSTRUCTIONS

OPCODE 0 -- NOP:

-1st clock: Nothing occurs; the fetch cycle resumes on the next clock pulse.


OPCODE 1 -- LDA:

-1st clock: The least significant 2 digits (operand field) of the IR are sent out 
on the address bus.

-2nd clock: MEMR becomes active on the control bus. This causes the contents of the 
selected memory cell to be placed on the data bus.

-3rd clock: The contents of the data bus are received by the ACC.


OPCODE 3 -- ADD:

-1st clock: The least significant 2 digits of the IR go out on the address bus.

-2nd clock: MEMR becomes active on the control bus causing the contents of the 
selected memory location to be deposited on the data bus.

-3rd clock: The contents of the data bus are received by register B inside the CPU.

-4th clock: The ALU's ADD signal is activated causing the contents of register B to 
be added to the ACC.  The result of the addition is stored back into the ACC.


OPCODE 6 -- OUT:

-1st clock: The least significant 2 digits of the IR go out on the address bus.

-2nd clock: The contents of the ACC go out on the data bus.

-3rd clock: IOW becomes active on the control bus causing the contents of the data 
bus to be received by the selected output port.


OPCODE 8 -- JN:

-1st clock: If the contents of the ACC are negative, copy the least significant 2 
digits of the IR to the PC; if not, do nothing. The result is that, if the ACC 
was negative, the PC will now be pointing to the jump address. The next fetch will 
then bring in the instruction stored at that address. If, on the other hand, the 
ACC was non-negative, the next fetch will bring in the next instruction in sequence, 
since, in that case, the PC was not altered.

OPCODE 9 -- HLT:

-1st clock: Stop the clock. The fetch-decode-execute cycle terminates.

PROGRAM EXECUTION

Let us now trace execution of the simple adding program we developed above. We 
assume that it has already been loaded into memory starting at address 0 and that 
the PC contains a 00. (On most real systems, the PC is automatically cleared to 
zero when the computer is turned on. There are, however, many other complexities 
involved in loading the first program into memory. We will not worry about those 
issues here.) We also assume that memory location 07 has already been loaded with 
53 and location 08 with a 41 (both specified in the program. The fetch-decode-
execute cycle is about to commence. The following table indicates what will be 
on the various buses and in the various cpu registers as each instruction is 
fetched and executed. Each line of the table represents the state of the machine 
after a new clock pulse arrives. In this table only changed entries are shown.

CLK   CPU REGISTERS               SYSTEM BUSES                   WHAT'S HAPPENING
#     PC  IR  ACC  B         Address         Control      Data
----------------------------------------------------------------------------------
      00                                                         Clock starts

1     00                     00                                  Begin 1st fetch
2                                            MEMR         107
3     01  107                                                    End 1st fetch

4                            07                                  Begin 1st execute
5                                            MEMR         53
6             53                                                 End 1st execute

7                            01                                  Begin 2nd fetch
8                                            MEMR         308
9     02  308                                                    End 2nd fetch

10                           08                                  Begin 2nd execute
11                                           MEMR         41
12                  41
13            94                                                 ADD to ALU
                                                                 End 2nd execute

14                           02                                  Begin 3rd fetch
15                                           MEMR         604
16    03  604                                                    End 3rd fetch

17                           04                                  Begin 3rd execute
18                                                        94
19                                           IOW                 Result to output port
                                                                 End 3rd execute

20                           03                                  Begin 4th fetch
21                                           MEMR         900
22    04  900                                                    End 4th fetch

23                                                               Begin 4th execute
Clock stops
A MORE COMPLICATED EXAMPLE

In this program we want to output the larger of two numbers stored in successive 
memory locations to port 1. In a high level language like C, the program would be 
something like:

int num1=13, num2=17;
if (num1 > num2)
        printf (num1);
else printf (num2);

A flow chart for this algorithm is shown below:



                ACC <-- NUM1
                 |
                ACC <-- ACC - NUM2
                 |
                 |        yes
                ACC < 0 ----------
                 |                |
                 | no             |
                 |                |
               ACC <-- NUM1       |
                 |                |
        ---------                 |
       |                          |
       |          <---------------
       |         |
       |       ACC <-- NUM2
       |         |
        -------> |
                 |
               Output ACC



One possible assembly language program that implements this algorithm on our machine 
(with assembler translation after pass 1 also shown) is as shown below. Note that 
during pass 1, the forward-referenced symbols SECOND and OUTPUT are not yet in the 
symbol table (shown below the listing) when they are first encountered by the 
assembler, and therefore the JN and JMP instructions cannot be completely translated 
during pass 1. Instead they are flagged.


MACHINE LANGUAGE                        ASSEMBLY LANGUAGE
address    contents           name     operation  operand    comment
-----------------------------------------------------------------------------------
10                                     ORG        10         ;start of data
10         13                 NUM1     DW         13         ;1st number
11         17                 NUM2     DW         17         ;2nd number
00                                     ORG        0          ;start of code
00         110                         LDA        NUM1       ;get 1st number
01         411                         SUB        NUM2       ;subtract 2nd
02         8??                         JN         SECOND     ;2nd is bigger
03         110                         LDA        NUM1       ;1st is bigger
04         7??                         JMP        OUTPUT     ;output result
05         111                SECOND:  LDA        NUM2       ;load 2nd
06         601                OUTPUT:  OUT        1          ;out to port 1
07         900                         HLT
                                       END




The symbol table at the end of assembler pass 1 would look like:

Symbol  Value
-------------------------------------------------------------------
NUM1    10      ;the value of the location counter for that symbol
NUM2    11      ;the value of the location counter for that symbol
SECOND  05      ;the value of the location counter for that label
OUTPUT  06      ;the value of the location counter for that label

During assembler pass 2, the two flagged instructions (the JN and the JMP) are 
examined again by the assembler. Now the symbols have values in the symbol table, 
so the machine language translation can be completed (8?? --> 805 and 7?? --> 706).
 
As an exercise, now try to trace execution of this program. Assume that it has 
already been loaded into memory starting at location 00. Fill in a table similar 
to that of the adding example above that illustrates what is contained in the 
various CPU registers and what is on the buses during each step of execution for 
each case. Repeat the exercise assuming that address 10 (NUM1) contains a 25 and 
address 11 (NUM2) a 22. What would happen if the two locations contained the same 
value?

As a second exercise,  write an assembly language program targeted for this machine 
that will multiply two numbers stored in successive memory locations. (Hint: one 
way of doing multiplication is to perform successive adds. For example, if you were 
multiplying 4 x 3, it would be equivalent to set an accumulator to zero and then 
add 4 to that accumulator three times. To implement this algorithm, you will need to 
reserve a memory location for the current value of the accumulator and another for 
the current "count".)