Labs for The Most Complex Machine
xComputer Lab 1: Introduction to xComputer
THIS LAB INTRODUCES the xComputer applet, which simulates a simple model computer (which is also called xComputer). The model computer is discussed in Chapter 3 of The Most Complex Machine. The xComputer consists of a Central Processing Unit (CPU) and a main memory that holds 1024 sixteen-bit binary numbers. The CPU contains an Arithmetic-Logic Unit (ALU) for performing basic arithmetic and logical computations. It also contains eight registers, which hold binary numbers that are being used directly in the CPU's computations, a Control circuit, which is responsible for supervising the computations that the CPU performs, and a clock, which drives the whole operation of the computer by turning its single output wire on and off.
The xComputer applet that you will use in this lab lets you load programs and data into the memory of the simulated xComputer. You can then watch while those programs are executed, and you can observe how numbers stored in the computer change as a program runs. The applet displays only the registers and main memory. You have to take the control circuit, ALU, and clock on faith.
This lab contains basic information about xComputer and its machine language. It demonstrates how instructions are fetched from memory and executed by the CPU. It will also explain the features of the xComputer applet and the process of programming the xComputer. The next lab will cover the programming process in more detail.
You would find it useful to read through Chapter 3 of the text before doing this lab. Chapter 3 is rather technical, and you might find that you need to work through both this lab and that chapter before you really understand either of them.
This lab includes the following sections:
- The xComputer Applet
- Writing Programs for xComputer
- Controlling Speed and Display Style
- Count and Store
Start by clicking this button to launch the xComputer applet in its own window:
(For a full list of labs and applets, see the index page.)
The xComputer Applet
The xComputer applet is divided into three sections. The right-hand third of the applet represents the main memory of the simulated computer. This section of the applet shows the 1024 locations in xComputer's memory. These locations are numbered from 0 to 1023. Each line in the memory shows a location number (in blue) and the value stored in that location. When the program first starts up, the memory contains only zeros. The scroll bar can be used to view any part of memory.
The "Control" section of the applet is used to interact with and control the xComputer. For example, you can use text-input boxes and buttons in the Control section to enter programs and data into the xComputer's memory. Once a program has been loaded into memory, you can tell the xComputer to execute it. You'll learn about controlling the xComputer as you work through the lab.
The "Registers" section of the applet shows the xComputer's eight registers. Remember that a register is simply a memory unit in the CPU that holds data being used directly in the CPU's computations. Each register plays a particular role in the execution of programs by the CPU. These roles are described in detail in the text and will be illustrated during the course of this lab, but here for your reference is a brief summary:
- The X and Y registers hold two sixteen-bit binary numbers that are used as input by the ALU. For example, when the CPU needs to add two numbers, it must put them into the X and Y registers so that the ALU can be used to add them.
- The AC register is the accumulator. It is the CPU's "working memory" for its calculations. When the ALU is used to compute a result, that result is stored in the AC. For example, if the numbers in the X and Y registers are added, then the answer will appear in the AC. Also, data can be moved from main memory into the AC and from the AC into main memory.
- The FLAG register stores the "carry-out" bit produced when the ALU adds two binary numbers. Also, when the ALU performs a shift-left or shift-right operation, the extra bit that is shifted off the end of the number is stored in the FLAG register.
- The ADDR register specifies a location in main memory. The CPU often needs to read values from memory or write values to memory. Only one location in memory is accessible at any given time. The ADDR register specifies that location. So, for example, if the CPU needs to read the value in location 375, it must first store 375 into the ADDR register. (If you turn on the "Autoscroll" checkbox beneath the memory display, then the memory will automatically be scrolled to the location indicated by the ADDR register every time the value in that register changes.)
- The PC register is the program counter. The CPU executes a program by fetching instructions one-by-one from memory and executing them. (This is called the fetch-and-execute cycle.) The PC specifies the location in memory that holds the next instruction to be executed.
- The IR is the instruction register. When the CPU fetches a program instruction from main memory, this is where it puts it. The IR holds that instruction while it is being executed.
- The COUNT register counts off the steps in a fetch-and-execute cycle. It takes the CPU several steps to fetch and execute an instruction. When COUNT is 1, it does step 1; when COUNT is 2, it does step 2; and so forth. The last step is always to reset COUNT to 0, to get ready to start the next fetch-and-execute cycle. This is easier to understand after you see it in action. Remember that as the COUNT register counts 0, 1, 2,..., just one machine language program is being executed.
You will learn how the xComputer works by giving it a short program and watching it execute that program. A program is a sequence of assembly language instructions. You have to enter the instructions into the xComputer's memory. But first, make sure that the "addr" input box in the Control area of the applet contains a zero. The number in this box specifies the address in memory where the instruction that you type will be stored. Then, type the following instructions into the "data" input box. Press return after each instruction (or, equivalently, click the "Data to Memory" button):lod-c 17 add-c 105 sto 10 hlt
When you press return, an instruction is translated into a machine language instruction and is stored in the xComputer's memory. (You'll actually see a number in the memory, rather than the assembly language instruction that you typed. For example, the instruction "lod-c 17" is represented by the number 25617.) Note that when you press return, the number in the "addr" input box is automatically incremented by one, to get ready for storing the next instruction that you type in the next memory location.
The first instruction of this program, lod-c 17, tells the xComputer to load the constant 17 into the accumulator. The second instruction, add-c 105 tells the computer to add the constant 105 to whatever number is in the accumulator and to put the result back into the accumulator. The sto 10 makes the computer copy the contents of the accumulator into memory location 10. And the final instruction, hlt, tells the computer to halt. The net effect is that the program adds 105 to 17 and stores the answer in location 10. After the program halts, you can look in memory at location 10 to find the answer.
Now, how do you make the computer run the program? All the computer ever does is fetch instructions from memory and execute them. The value stored in the PC register tells the computer which memory location to go to to get the next instruction. Before running the program, you have to make sure that it will begin with the first instruction of the program, which is in memory location zero. This means that the PC register should contain a zero. If this is not the case, you can put a zero into the PC by clicking the "Set PC = 0" button in the Control section of the applet. (Zero is the most common starting value for the PC, but if you want to start at a different location, you can type the address of that location into the "addr" input box and click the "Addr to PC" button.)
Once you have checked the value of the PC register, you can just click on the "Run" button to run the program. You should think of this as turning on the xComputer's clock. As soon as you do this, the clock stars ticking, the value in the COUNT register starts changing, and the fetch-and-execute cycle proceeds. This will continue until the computer executes a HLT instruction, or until you stop it.
You should Try this now. Make sure that the PC contains a zero. Then, click on the "Run" button. If you have done everything correctly, the program will run. You will see things happening, although you will probably not really understand them at this point. But you will notice that the instructions in the program appear one by one in the IR register as they are executed. Eventually, the HLT instruction will be executed and the computer will stop running. The correct answer to the computation, 122, will be in memory location 10. This gives you the general idea of how programs are executed by xComputer. Your goal in the rest of the lab is to understand the details.
After running the program once, you should run it again. First, reset the PC to zero. This time, instead of using the "Run" button, use the "Cycle" button. Clicking on "Cycle" makes the computer run, but only until the value in the COUNT register is 2. At that point, the computer has just loaded a new instruction into the IR and is about to execute that instruction. When you click on "Cycle" again, the computer will execute that instruction and fetch the next instruction. Thus, the "Cycle" button lets you step through a program one instruction at a time. Try it! Keep clicking on "Cycle" until you get to the HLT instruction.
Finally, you can run the program one more time, this time with the "Step" button. Clicking on the "Step" button makes the computer perform a single step in the fetch-and-execute cycle. You have to click on it several times just to execute one instruction in the program. Once again, you should reset the PC to zero. Then, click through your program with the "Step" button until the HLT is executed.
Writing Programs for xComputer
It should be clear that entering a long program into xComputer by typing it into the "data" box would be very tedious and error-prone. If you accidentally leave out one instruction, for example, you might have to retype most of the program! Fortunately, the xComputer applet lets you type a complete program in a separate text-input area and then translate the whole program at once and store it in xComputer's memory. This has three advantages: You can edit the program in the window, for example by inserting a new instruction. You can (if the configuration of your Web browser permits it) save the program in a file, so that you'll never have to retype it again. And you can use labels in your program. Labels are a powerful programming technique; they are described in the Postscript to Chapter 3 in the text. They are not covered in this lab, but they will be an important part of the next lab.
If you want to type a new program, just click on the "New Program" button in the Control area of the applet. Alternatively, you can select "[New]" from the pop-up menu at the very top of the applet. The computer display will disappear and will be replaced by a text-input area when you can type your program. Enter the following program into that text area:lod-c 1 sto 12 lod 12 inc sto 12 jmp 2
This program counts. It starts by putting the number 1 into memory location 12, and then it adds one to the number in that location over and over, forever. (You'll see this in action in a moment.) There are several new instructions here. Lod 12 tells xComputer to copy the number from memory location 12 into the accumulator. (Note how this differs from lod-c 12, which puts the number 12 itself into the AC, rather than the number stored in memory location 12.) The inc instruction adds one to the value in the accumulator. And jmp 2 is a jump instruction that sends the computer back to location 2.
After typing this program, click on the "Translate" button that is located below the text area, on the left end of a row of buttons. If the program contains some error, an error message will be displayed. If you've typed the program correctly, it will be translated into machine language and stored in the xComputer's memory. The text area will be replaced by the computer display, and the computer will be ready to run the program. Click on the "Run" button to run the program and see how it operates. You can watch as the PC counts off the instructions in the program. You will see the assembly language instructions themselves as they are loaded into the IR. And you can observe that the value in memory location 12 changes from 1 to 2 to 3 to 4 and so on. This program will run forever, if you let it.
You will be working with this little program throughout most of the remainder of the lab. Your objective is to understand how xComputer operates and to appreciate the fetch-and-execute cycle.
Controlling Speed and Memory Display Style
As you let the counting program run, you can try varying the speed at which the computer executes instructions by changing the setting on the speed pop-up menu (located just below the "Run" button. The lower speeds allow you to watch what is happening in more detail. The higher speeds allow the computer to get more done. At the very highest speed, the registers are not displayed, so that the computer can run as quickly as possible, without updating the register display all the time.
When you have had enough of this, stop the program and experiment with the memory display style pop-up menu, which is located just above the scrolling memory display. This menu allows you to select how you would like to view the contents of main memory. (There is also a similar pop-up menu for setting the register display style.) Of course, the actual contents of memory are binary numbers, but a binary number can mean many things, depending on how it is interpreted. When the applet first starts up, it is set to display the contents of memory as ordinary decimal integers in the range -32768 to 32767. This is only one possible interpretation of the binary numbers that are stored in memory. Using the display style pop-up menu, you can select from six different interpretations:
- The Instructions display shows the contents of each memory location as an assembly language instruction. In this display style, you should see the original counting program in memory locations 0 through 5. Most of the other locations contain Add 0, which just happens to be the assembly language instruction encoded by the 16-bit binary number 0000000000000000. (Since not every 16-bit binary number corresponds to a legitimate assembly-language instruction, you might see some funny things in this display style.)
- The Integers and Unsigned Ints displays show ordinary decimal integers. The difference is that signed 16-bit integers are in the range -32768 to 32767, while unsigned 16-bit integers are in the range 0 to 65535. (In either case, there are 216 different possible values -- it's just a question of how they are interpreted. See Subsection 2.2.3 in the text.)
- The Binary display shows a 16-bit binary number in each memory location; this display style is closest to the actual physical contents of the memory.
- The ASCII display interprets each sixteen-bit number in memory as made up of two eight-bit ASCII character codes, and shows the two characters. Some eight-bit binary numbers do not represent visible ASCII characters. These numbers are shown in the form <#N>, where N is the number, in decimal form. Thus, for example, the 16-bit binary number 0000000000000000 is shown in ASCII display style as <#0><#0>.
- The Graphics display is very different from the others. It shows the entire memory at once. Each bit in memory -- all 16 times 1024 of them -- is represented by one pixel on the screen. That pixel is white if the bit is zero and is black if the bit is one. If you choose the Graphics display now, the memory will be almost entirely white, except for a few black dots at the top that represent the program you entered into memory.
You can try out the various memory display styles. You'll be using them in Exercise 1 at the end of the lab. I should note that when you enter information into Memory using the "data" input box in the Control area of the applet, you can type the information in several of the above display styles, as well as in assembly language. You can, for example, enter ordinary numbers in the range -32768 to 65535. You can enter a binary number, but you must precede it by the letter B. For example: B1011010111. Finally, you can enter one or two ASCII characters, but you must precede them by a quote mark. For example: '#1 or 'A. You will need to do this for Exercise 1.
There is another option in the pop-up menu: "Control Wires". This display style doesn't show memory at all. If you select it, the computer's memory display will be replaced by a list of control wires. These control wires are the key to understanding how the xComputer works. The basic idea is that turning control wires on and off makes things happen in the computer. They are turned on and off by a Control Circuit, and they control the operation of other components of the CPU. Each control wire has a function. Turning that wire on causes something to happen, such as moving a number from main memory into the AC register or adding the numbers in the X and Y registers and putting the answer into the AC. Executing a program is just a matter of turning the right wires on and off in the right sequence.
The "Control Wires" display lets you see what wires are turned on during each step in the execution of an instruction. Try it with the instruction lod-c 17, by doing the following: First, enter the instruction "lod-c 17" into some memory location, and set the PC to the address of that location. Next, set the display style to "Control Wires". Then, use the "Step" button to go through the fetch-and-execute cycle one step at a time. Here's what you will see:
- First click on the "Step" button: COUNT becomes 1, indicating that the first step in the fetch and execute cycle is being performed. The Load-addr-from-PC control wire is turned on, and the value in the PC register is copied into the ADDR register. (The PC register tells which memory location holds the next instruction; that location number must be copied into the ADDR register so that the computer can read that instruction from memory.)
- Second click: COUNT becomes 2. The Load-IR-from-Memory control wire is turned on, and an instruction is copied from memory into the IR. (The ADDR register determines which instruction is read.) In this case, the instruction is Lod-c 17.
- Third click: COUNT becomes 3. The Increment-PC control wire is turned on, and the value in the PC register is incremented by 1. Ordinarily, this prepares the PC for the next fetch-and-execute cycle. This completes the "fetch" portion of the fetch-and-execute cycle. The remaining steps in the cycle depend on the particular instruction that is begin executed (in this case, lod-c 17).
- Fourth click: COUNT becomes 4. The Load-AC-from-IR control wire is turned on. The data part of the instruction in the IR register, is copied into the accumulator. In this case, the value is 17. This is the only step necessary to execute the lod-c 17 instruction.
- Fifth click: COUNT becomes 5, but only briefly. The Set-COUNT-to-Zero control wire is turned on and immediately the value of COUNT is reset to 0. One fetch-and-execute cycle is over. (On the next click, COUNT would become 1 again, and the next cycle would begin.
As you click on the "Step" button in this exercise, you are actually simulating the role of the xComputer's clock. Each click has the same effect as one tick of the clock, and you are driving the computation at your leisure in the same way as the ticking of the clock usually drives the computer with its regular ticking.
Count and Store
For the last part of the lab, consider the following program, "CountAndStore". This program should have been automatically loaded by the xComputer applet, so you won't have to type it in. Just select it from the pop-up menu at the top of the applet, and click on the "Translate" button to store it in the xComputer's memory. Note that in an xComputer program, anything that comes after a semicolon on a line is a comment, which is meant for human readers. Comments are ignored by the computer.lod-c 1 ; Start with a 1 in location 12 sto 12 lod 12 ; This instruction is stored in location 2 inc sto 13 ; This instruction is stored in location 4 lod 2 ; Add 1 to the number in location 2 inc sto 2 lod 4 ; Add 1 to the number in location 4 inc sto 4 jmp 2 ; Go back to the instruction in location 2
This program is similar to the simple counting program that you looked at earlier in the lab, except that the number for the second sto command has been changed, and six new instructions have been inserted before the jmp command. The instructions "lod 2, inc, sto 2" add 1 to the number stored in memory location 2. But if you look at what's stored in that location, you'll find the instruction lod 12, which is part of the program. This seems odd. What happens when you "add 1" to an instruction?
Remember that machine language instructions are really just numbers. There is no problem with adding 1 to a number. However, the meaning of the instruction represented by the number is changed. If you add 1 to the number that encodes "lod 12," the meaning of the answer is "lod13." If you want to understand exactly why this is true, look at the binary representations of the machine language instructions. (The details are given in Section 3.2 of the text, if you want to check there.)
Run this program and see what it does. To fully appreciate this program, you should run it at "Fastest Speed" with the memory display set to "Graphics". You can watch as the memory is gradually filled with numbers.
Exercise 1: You can use the xComputer to translate from one type of data to another by entering it in one form in the "data" input box and viewing it in memory in another form. Use this method to do the following conversions, and explain briefly how you do each part:
- Find the ASCII code for the character #. (The ASCII code is the integer that represents this ASCII character.)
- Find the character whose ASCII code is 99.
- Find the binary representation of -233.
- Find the unsigned integer that has the same binary representation as the signed integer -233.
- Find the unsigned integer that represents the assembly language instruction sto 1023.
- Now, Add 1 to the number that represents sto 1023 and find the assembly language instruction represented by the resulting number. Why do you get a completely different instruction? (Note: Do the addition yourself; you don't have to program the computer to do it!)
Exercise 2: In reality, the memory of a computer contains only binary numbers. Machine language, in particular, consists of binary numbers. Translate the counting program, which is repeated below, into the binary numbers of machine language, and write a paragraph or two explaining why computers use binary numbers instead of something more readable.lod-c 17 sto 12 lod 12 inc sto 12 jmp 2
Exercise 3: Write an assembly language program that computes 34 - 17 + 103 - 12. The instruction for subtracting a constant from the accumulator is sub-c.
Exercise 4: Earlier in the lab, you were asked to step through the execution of the instruction lod-c 17, which tells the computer to load the number 17 into the accumulator. The instruction lod 17 tells the computer to copy the contents of memory location 17 into the accumulator. Use xComputer to watch as this instruction is executed step-by-step, just as you did above for the lod-c 17. Enter a lod 17 instruction into memory location zero, and reset the PC to zero. Set the display style to "Control Wires". Then use the "Step" button to step through the fetch-and-execute cycle as the lod instruction is executed. Write down what happens during each step. Carefully explain the purpose of each step in the execute phase of the cycle (steps 4 and later). What differences do you find between the execution of a lod-c instruction and the execution of a lod instruction? How can the differences be explained in terms of what the instructions do?
Exercise 5: Use the "Step" button to trace the execution of an add-c instruction and of an add instruction. (See Exercise 4 for detailed instructions about how to do this.) Record the control wires that are on during each step in the execute part of the fetch and execute cycle, that is for steps number 4 and later, and carefully explain the purpose of each of those steps. What differences do you observe between these two instructions? How can the differences be explained in terms of what the instructions do?
Exercise 6: Carefully explain why the first three steps of the fetch-and-execute cycle are always the same, and why they have nothing to do with the contents of the instruction register.
Exercise 7: Modify the first counting program used in this lab so that it will count just from one to sixteen, stopping when it reaches sixteen. (The program is repeated below.) To do this, each time through the loop, you need to test whether the number is sixteen. If it is, jump to a HLT instruction at the end of the program. Testing whether a number is sixteen requires two steps: First, subtract 16 from the number, and then test whether the answer is zero. Use a JMZ instruction to test whether the answer is zero. (This is like a JMP instruction, except that the jump only occurs if the number in the AC is zero.) Write a paragraph explaining how your program works.lod-c 1 ; This is the original counting program. sto 12 lod 12 inc sto 12 jmp 2 hlt ; Add a halt instruction at the end.
Exercise 8: Describe what is done by the "CountAndStore" program, which you encountered earlier in the lab. Discuss how it works in some detail. To do a good job on this exercise, you will have to step through several executions of the loop in the program and study how it works.
Exercise 9: Discuss what you learn from the "CountAndStore" program about "data" and "instructions" and the relationship between them. (The memory of a computer can hold both data and instructions. How does the computer distinguish between them? Does it?)
Exercise 10: Run the "CountAndStore" program at "Fastest Speed" with the display set to "Graphics." If you let the program run long enough, it will halt. How is this possible, since the program contains no HLT instruction? To figure this out, you'll need to do some detective work after the program ends. Look at what has happened to the program in the computer's memory. Try to be as explicit and complete with your explanation as possible. This is not an easy question. (Hint: something you did in Exercise 1 turns out to be relevant here.)
This is one of a series of labs written to be used with The Most Complex Machine: A Survey of Computers and Computing, an introductory computer science textbook by David Eck. For the most part, the labs are also useful on their own, and they can be freely used and distributed for private, non-commercial purposes. However, they should not be used as a formal part of a course unless The Most Complex Machine is also adopted for use in that course.
--David Eck (firstname.lastname@example.org), Summer 1997