xComputer Info

A computer stores programs and data in its main memory (or "RAM"). It has a central processing unit (or "CPU") that fetches instructions from memory, one-by-one, and executes each instruction. This is called the fetch-and-execute cycle. A single fetch-and-execute cycle is itself made up of small steps. Each of these little steps performs a very simple operation, such as copying data from one location inside the CPU to another, adding two numbers, or moving information between main memory and the CPU. Each step is accomplished by turning control wires on and off. These control wires are attached to the main memory and to various components in the CPU. A control circuit turns the control wires on and off, based on just a few pieces of information, including the instruction that is being executed and the value of a counter that counts off the little steps of each fetch-and-execute cycle. All the values that CPU is currently working with are stored in registers, which are small memory units contained within the CPU. The whole process is driven by a clock. Each time the clock ticks, one step of a fetch-and-execute cycle is performed.

That's a very brief description of the fundamental operation of a computer. With some extensions, it is true of all existing computers. The xComputer applet simulates this fundamental operation for a computer with a 1024-location RAM and eight registers. Like any computer, the xComputer has a certain set of machine language instructions that it understands. Machine language instructions are actually binary numbers and are not really meant to be read or written by humans. Programs for the xComputer are therefore usually written in assembly language. An assembly language program must be translated into machine language before it can be executed by a computer. The assembly language for xComputer has 31 different instructions, which are listed below.

The xComputer and its assembly language are discussed in detail in Chapter 3 of The Most Complex Machine. This page does not cover all the details, but it should have enough information to enable you to use the applet and even to write some assembly language programs.


The xComputer Applet

The point of the xComputer Applet is to illustrate the step-by-step operation of a computer as it executes a program. When the applet starts up, it displays three sections: A "Control" area, a set of "Registers" and a "Memory." The Memory is a scrolling list occupying the right-hand third of the applet. It displays 1024 memory locations, numbered from 0 to 1023. Each location contains a 16-bit binary number that can be interpreted either as data or as a machine language instruction. The Registers section of the applet shows eight registers that are components in the xComputer's Central Processing Unit. The registers are explained below. Finally, the Controls are for interacting with and controlling the xComputer.

The applet has another mode in which it displays a text-input area where you can write and edit assembly language programs. (Information about the assembly language of xComputer is given below.) To start a new assembly language program, just click on the "New Program" button in the Control area of the applet. Alternatively, choose "[New]" from the pop-up menu at the very top of the applet. There is also a "Load File" button that can be used to load a program that has been previously saved to a file; however, you can only do this if your browser permits applets to access files. Programs that have been created or loaded are listed in the pop-up menu at the top of the applet. You can view any program by selecting it from this menu. You can return to main computer screen by selecting "Computer" from this menu.

Suppose that you are looking at an assembly language program in programming mode. Before xComputer can do anything with that program, it must be translated into machine language and put into xComputer's main memory. When the applet is in programming mode, there is a "Translate" button at the bottom of the applet that will attempt to do this. If an error is found in the program, an error message will be displayed. (You can rid of this message by clicking on it, if you like.) If the program contains no errors, it will be put into xComputer's memory and the applet will switch to the main computer screen. You can then run the program or step through it, as described below.

Short programs can also be entered directly into memory from the Control area of the xComputer screen. Information that you want to put into memory -- instructions or data -- can be entered into the text-input box labeled "data:". When you press return or click the "Data to Memory" button, the data is stored in memory. The location in memory where it is stored is specified by a number in the "addr:" text-input box. You can only enter data for one memory location at a time. Each time you enter data, the number in the "addr" box is automatically incremented by one. This lets you store information into successive memory locations simply by typing values and pressing return after each one.

The question remains, exactly what sort of thing can you enter into main memory? The first thing you need to understand is that what is really in each memory location is a 16-bit binary number. Any other form of information must be represented in this form. The same binary number can represent different values, depending on how it is interpreted. You can enter information in the "data" box in any of the following ways:

When you type any of these things in the "data" box and press return, it is translated into a binary number and put into memory at the specified address. (If there is some error in what you type, you'll get a small error message above the "addr" box.) So, a binary number in memory can represent several different things. The xComputer applet allows you to view the contents of memory in several different forms. Select the view that you want from the pop-up menu above the memory display. The "Instructions", "Integers", "Unsigned Ints", "Binary", and "ASCII" display styles correspond to some of the data types listed above. (In the ASCII display style, two characters are shown in each memory location. Non-printing characters are shown as ASCII code numbers enclosed between < and >. For example, <#17> represents the character with ASCII code number 17.) The "Graphics" display shows all of memory at once, as a rectangle full of black and white dots. Each dot represents one bit in memory. A black dot represents a one, and a white dot represents a zero. The rectangle is 64 bits wide, with each row of dots representing four memory locations of 16 bits each. The "Control Wires" display style actually doesn't have anything to do with memory at all. I'll discuss it below.

For example, here is a short assembly language program that adds the numbers 105 and 17, stores the answer into memory location 10, and then halts:

                lod-c 105
                add-c 17
                sto 10
                hlt

You could enter this program directly into memory by typing the lines, one at a time, into the "data" box. Note that what you see in memory depends on the setting of the memory display style. You might want to try entering this program, and use it as an example as you read the next section.


Running a Program

A program consists of a series of instructions stored in memory. The computer fetches instructions one-by-one and executes them. The program counter register (or "PC") tells the computer which address to go to in memory for the next instruction. When you want to run a program, you should always first check that the value in the PC register is the address of the location that contains the first instruction of the program. You can set the value in the PC to zero using the "Set PC=0" button. To set the PC to some other value, type the value into the "addr" box and then click on the "Addr To PC" button. This is important. A common, frustrating mistake when trying to run a program on xComputer is simply to forget to tell xComputer where in memory the program is located! (Note: If you use the "Translate" button in programming mode to put a program into memory, the PC will automatically be set to zero at the same time. However, after you run the program once, you have to reset the PC manually if you want to run it again.)

Once you have set the PC, there are three different ways to run the program:


Registers and Control Wires

The xComputer has eight registers. A register is a memory unit that holds one binary number. Different registers holds different numbers of bits. Each of the registers has a role to play in fetching and executing instructions. Here is a short description of the purpose of each register:

The X and Y registers are connected to the inputs of an Arithmetic-Logic Unit, or "ALU", which does all the arithmetic and logical calculations in the computer. The outputs of the ALU are connected to the AC and to the FLAG register. (The ALU is not shown in the xComputer applet.)

The components of the computer -- including the main memory, the registers, the clock, and the ALU -- are controlled by turning wires on and off. These wires are connected to various components of the computer, and they control the operation of those components. It is these " control wires" that make the steps of the fetch-and-execute cycle happen. You can see a list of the control wires in xComputer by selecting the "Control Wire" option from the memory display pop-up menu. The wires that are currently turned on are shown in red. As a program is executed, the wires that are on change during each step of each fetch-and-execute cycle. You can watch how they change in order to learn how each step is accomplished.

For example, in step #1 of each fetch-and-execute cycle, the control wire named "Load-ADDR-from_PC" is turned on. This causes the number stored in the PC -- which is the location of the instruction that is to be fetched -- to be copied into the ADDR register -- where it sets up the main memory for reading from that location. The purposes of most of the wires are clear from their names. (The seven wires at the top of the list, starting with "Select-Add" are connected to the ALU. The ALU can perform several different calculations. The Select wires are used to tell it which calculation it should do.)


The Assembly Language of xComputer

An assembly language program is simply a way of specifying a sequence of 16-bit binary numbers to be stored in the computer's memory. As such, it can include any of the data items described above: Assembly language instructions, numbers in the range -32768 to 65536, hexadecimal numbers (up to four digits, preceded by $), binary numbers (up to 16 bits, preceded by B or b), and ASCII characters (one or two characters, preceded by a single left quote mark).

The legal instructions are listed below. An instruction consists of a two- or three-character code, such as LOD, OR, and HLT. Since upper and lower case letters are not distinguished, these could also be written as lod, or, and hlt. In some cases, this instruction code can be followed by an addressing mode, indicated by "-C" for "constant" addressing mode and by "-I" for "indirect" addressing mode. The addressing mode indicates how the data for the instruction is to be used. For example, ADD-C 17 indicates that the constant, 17, is to be added to the number in the accumulator, while ADD 17 indicates that a number is to be read from memory location 17 and that number is to be added to the number in the accumulator.

As you can see, the data for the instruction simply follows the instruction. It must be on the same line. You can't split instructions over two lines, and you can't have more than one instruction on a line. Not all instructions need data. If you provide data for an instruction that doesn't need it, it is legal, but the data will be ignored when the instruction is executed. The data for an instruction is a 10-bit binary number. It can be given in any of the following forms:

The last possiblilty -- a label name -- brings us to a whole new aspect of assembly language. An assembly language program can contain more than just a sequence of items representing 16-bit numbers. It can contain other things to make programming easier by letting the computer do more of the work. A label is a name that stands for a number. A label represents a 10-bit binary value and can appear anywhere in the program where such a value could be used, that is, as the data part of an instruction or as a stand-alone item on a line by itself. When the program is translated, the label is replaced by the number it represents. A label is given a value by using it to label one of the 16-bit items that make up the program. The label name must be followed by a colon (:) and the item that it labels. The value of the label is the address of the location in memory that contains that item. For example, the following program adds up all the numbers from 1 to 50:

               lod-c 1       ; Initialize number to contain 1.
               sto number
               lod-c 0       ; Initialize sum to contain 0.
               sto sum
         next: lod sum       ; Add current value of number to sum.
               add number
               sto sum
               lod number    ; Add one to the value of number.
               inc
               sto number
               sub-c 51      ; Subtract 51 from the number, which is still in AC.
               jmz done      ; If the answer is zero, jump to "done".
               jmp next      ; Otherwise, jump to "next" to continue the computation.
         done: hlt           ; Halt. 
          sum: 0             ; (The zeros are place-holders to reserve memory
       number: 0             ;     locations for sum and number.)

In this program, next, done, sum, and number are labels. Next and sum refer to locations that hold instructions. Sum and number refer to locations that hold data for the program. The programmer can work with the instructions and data without having to work out the actual location numbers. (This program also illustrates comments. Anything on a line after a semicolon (;) is treated as a comment and is ignored by the computer.)

There are a few more things you can do in an assembly language program. A program item can be preceded by a number followed by a #. This is a repetition count and is the same as typing the item the specified number of times. For example, "25# 17" puts a 17 in each of the next 25 memory locations. "4# SHL" is equivalent to four SHL instructions in a row.

Ordinarily, a program is loaded into consecutive memory locations starting at location 0. However, you can specify where loading is to take place by using the character @ followed by an address. For example, "@100" specifies that the next item is to go into memory location 100. (Items following that one will then go into location 101, 102, etc.) You might use this feature to put "subroutines" at specific points in memory.

Finally, you can store a string of ASCII characters into consecutive memory locations by using a string. A string is just a series of characters enclosed between double quotes, such as "Hello World!". When the computer encounters a string in a program, it stores the characters in consecutive memory locations, one per location.


List of Assembly Language Instructions

Here is a complete list of the assembly language instructions for xComputer. In this listing, "X" is data for the instruction; it must translate into a 10-bit binary number.


David Eck (eck@hws.edu),
June 1997; minor editing May 1998