Experiment 1 - Working with Registers
Programming is the process by which a task is broken down into a set of instructions that can be performed by a computer. Typically, programs consist of instructional blocks classified in one of three ways or control structures: sequence, selection, or iteration. Sequence means that instructions within a block are performed in a specified order. Selection means that, within a block of instructions, a selection is made between alternative sub-blocks of instructions based on a condition. Iteration means that a block of instructions is performed repeatedly based on a condition. Computer microprocessors like the Intel 8080 and its successors are designed to perform all three. In Experiments 1, 2, and 3 we will explore sequence structure. In later experiments, we will explore selection and iteration.
In the first few experiments, we will code our programs in machine language. Our coding examples will be simple, short, and intended to illustrate the very basics of microprocessor operation. In later experiments, as our programs grow more lengthy and complex, we will code with assembly language. But to get started, we will flip switches and watch lights blink as in the old days!
In the Beginning . . .
The Intel 8080 microprocessor was released in 1974 and became one of the most popular microprocessors of its day. The Intel 8080 is an 8-bit microprocessor, meaning that most of its operation centers around registers and memory that is 8-bits wide. There are seven 8-bit, working registers. The "A" register is called the accumulator because it receives or "accumulates" the results of arithmetic and logical operations. The remaining working registers are designated B, C, D, E, H, and L. They perform "scratchpad" duty, holding values for various operational and computational purposes. The Intel 8080 can directly address 65,536 bytes of 8-bit memory in which programs and data are stored. To communicate with the outside world, the Intel 8080 directly addresses up to 256 8-bit digital input/output (I/O) ports.
The Intel 8080 is a primitive microprocessor by modern standards. It consists of three functional units: 1) Registers (see above), 2) Arithmetic/Logic Unit (ALU), and 3) Control Circuitry. Memory and peripherals are external. By contrast, the ATMEL ATmega328 that we will work with later has the same three functional units plus on-chip memory of various types and several useful peripherals. For a more complete description of the Intel 8080 architecture, refer to the user's manual.
The Intel 8080 has 78 machine language instructions. Each instruction consists of one 8-bit code byte followed by none, one, or two additional 8-bit data bytes. The code byte generally represents an operation and the data byte(s) represent a related operand. For instance, the operation might be to add a constant value to the accumulator. The "add immediate" code byte (the operation) would be followed by a data byte (the operand). The second operand would be in the accumulator. This experiment will familiarize you with the Intel 8080's working registers and the instructions used to move data into, out of, and around them.
When working with Intel 8080 machine language, octal turns out to be a good way to designate Intel 8080 code bytes. The reason is that many Intel 8080 instructions are constructed around octal representation of the working registers. The table below shows the binary and octal values associated with each register.
Register Reference Number ( r ) | ||
Register | Binary | Octal |
A | 111 | 7 |
M 1 | 011 | 6 |
L | 101 | 5 |
H | 100 | 4 |
E | 011 | 3 |
D | 010 | 2 |
C | 001 | 1 |
B | 000 | 0 |
1 M designates a "memory register" and is used to extend operations to indirectly addressed memory. We will explore its use in a later experiment.
Note: For this experiment and when it is not otherwise obvious, the suffix B for binary and Q for octal will be used for constants other than decimal. For instance, 100 (decimal) would be 01100100B (binary) and 144Q (octal).
To see an example of octal register referencing, consider the Intel 8080 "move immediate" instructions shown in the table below. For immediate instructions, the code byte is "immediately" followed by a numeric data byte to be loaded (moved) into the working register referenced. The middle digit in the MVI code byte is "r" as given in the Register Reference Table. We could write the octal MVI code byte as "0r6" where r is the register reference number. For instance, "MVI A" is "0 7 6" since r = 7 for register A.
Move Immediate Instructions | ||
Instruction | 0 r
6 Code Byte (Octal) |
00 r 110 Code Byte (Split Binary) |
MVI* A,v | 076 | 00 111 110 |
MVI M,v | 066 | 00 110 110 |
MVI L,v | 056 | 00 101 110 |
MVI H,v | 046 | 00 100 110 |
MVI E,v | 036 | 00 011 110 |
MVI D,v | 026 | 00 010 110 |
MVI C,v | 016 | 00 001 110 |
MVI B,v | 006 | 00 000 110 |
* In computer assembler coding, an instruction mnemonic like MVI is a symbolic name for a machine language code byte . Later, when we switch from machine to assembly coding, we'll use easier to remember instruction mnemonics and let the assembler make the code byte translation for us.
To take advantage of octal register referencing while machine coding, we will write code and data bytes in octal. For addresses, we will split the address into two groups of octal digits. The first group we refer to as the "page"; the second group we'll call the "location" on the page. The Intel 8080's memory consists of 256 pages of 256 bytes each for a total of 256 * 256 = 65,536 bytes. Each page, in turn, consists of 256 locations. The first address in the Intel 8080's memory space is 000 000Q and the last address is 377 377Q. We would read address 127 341Q as location 341Q on page 127Q. The WhippleWay Front Panel 8080 conveniently spaces address check boxes and data LEDs in two and three-bit groups to make octal representation easier.
Suppose for example we want to program "MVI A, 10"; i.e., load the A register with decimal value 10. The machine code would be written as follows:
Memory Address ( Split Octal) |
Code (Octal) |
Description |
000 000 | 076 | The "7" refers to the A register while the "0" and "6" designate this as a "move immediate to register" instruction. |
000 001 | 012 | 012Q is the octal equivalent of decimal 10; i.e., 0 * 8^2 + 1 * 8^1 + 2 * 8^0 = 0 + 8 + 2 = 10. |
We are about to begin using the Front Panel 8080. Please become familiar with the operating specifications found here.
Try it!
Example 1. Move the decimal value 10 to the A register and display the result in the Data LEDs.
Example 2. Load register B with 125Q and then move it to A for display.
Change the "7" in 076Q to the appropriate r value for B in the Register Reference Table. MVI B is then 006Q. To check whether it works, use the MOV (move) instruction to move data from the B to A for display. For the Intel 8080, the move instruction is simply "1" followed by the destination register rd and the source register rs or "1 rd rs.". MOV A,B is 170Q. It's that simple. Just remember the order is "destination" then "source"!
Something to think about
The simple task we performed in Example 2 was to load a value in the B register and then move it to the A register. This is an example of sequence structure; that is, a block of instructions each executed in a specific order. Execution begins with the first instruction (MVI B, 125Q) and proceeds instruction-by-instruction until the last instruction (MOV A,B) is executed. For it to conform strictly to sequence structure, neither entry after the first instruction nor exit before the last instruction is allowed. We will see later that not all tasks can be performed with sequence structure alone. Selection and iteration structures will be required.
Continue to next Experiment - Click Here