So this post is a little out of the ordinary, however I figured this nice rant about the history of computer technology may be useful to some readers out there.
The History of Computer Technology
The first computer built in America was the IAS computer. It was developed at the Institute for Advanced Study at Princeton under the direction of John Von Neumann between 1946-1950.
This obsolete machine’s architecture is presented not just for its historical significance, though that would be reason enough. Details about it are presented because many (most) modern computers (including the HCS08) trace their ancestry to the IAS machine. Those that do are referred to as von Neumann (or Princeton) architecture machines. The IAS architecture is relatively simple and is a convenient starting point for assembly language programming. An assembly language program for the IAS (though programs for it were written in machine language) would not look very different from modern load/store style machines. Also, a sense of the relative importance of concepts results from learning the IAS architecture. Programs written in a carefully selected subset of the HCS08 instruction set would look almost identical to an IAS assembly program (were we to create an assembler for that machine). We will then see how the complete HCS08 instruction set improves on the IAS instruction set and addressing scheme. The general design of the IAS machine is given below. The HCS08 is almost identical to it.
As originally designed (to cut costs the machine was built with less memory), the memory consisted of 4096 40-bit words. The number of words in computer memory systems (at least the maximum memory) always consists of a power of two. This is because the specific word in memory to be accessed at any given time is specified by a set of binary valued wires or lines called the address bus. The number of different locations in memory such a bus can specify is simply all the possible combinations of the two values possible on each of the lines. For an n-bit bus, that value is 2n. The address bus size for the IAS memory was therefore 12 providing for 212 = 4096 unique memory locations. The number of bits per word is up to the computer designer. Memory word sizes of 4, 8, 12, 16, 18, 24, 32, 36, 40, 48, 60, and 64 have all existed for some computer. Almost all computers made today use 8-bit memory words, although they all support data types that use several consecutive memory words together as a single value. Most desktop (or larger) computer systems support 8-bit, 16-bit, 32-bit, and 64-bit values. Some even support 128-bit values. Note, all of these sizes are multiples (in fact powers of 2 multiples) of the basic 8-bit word size so these values use 1, 2, 4, and 8 (some even 16) words, respectively. Whatever the memory size, anyone with some programming experience taking their first look at the memory system in a computer design, should think of the memory as an array with 2n elements. The address bus carries the value of an n-bit unsigned index into the memory array. The data bus returns (or supplies if a write instead of a read is issued) the m-bit memory word value of the specified element, where m is the word size (in bits) of the memory system.
The REGS component of the general design represents the register set used by the CPU (Central Processor Unit). Registers are fast special-purpose memory separate from the main memory. They support the fetching and execution of instructions stored in memory. The registers in the IAS design are given below:
IAS Instructions and Data
The IAS computer embodied the concept of a stored-program computer. The main memory contained two main categories of information – instructions and data. It is the ability to place different sequences of instructions in the memory that makes the computer so useful – it is what makes it a general-purpose computing device rather than a special-purpose or single-function computer. Instead of being constrained to building computers that perform only predefined single tasks (or small set of tasks), we can build a computer that does different tasks at different times. Such a computer can be reconfigured (reprogrammed) at any time to perform a new or different task. Often an important task is not even conceived of at the time the computer is designed. For the IAS machine, it was important that the programs and data shared the same memory. That way the instructions themselves could be processed as other data values. Self-modifying programs were the only scheme that the IAS designers thought of for performing loops that worked on different array elements each time through the loop. Between iterations of the loop, the instructions that accessed the array element were loaded into the AC and a value added to them to change the address portion of the instruction to the next array element to be processed. The modified instruction was then stored back in its memory location for execution the next time through the loop. Computer designers have since come up with several methods of accomplishing this type of operation without modifying the instructions themselves. Today, self-modifying code is considered taboo, as it is prone to logic errors that are hard to discover, cannot be executed out of Read-Only Memory (ROM), and other deficiencies that are beyond this article.
IAS Instruction Sets
The IAS instructions consisted of 20 bits – a 12-bit address and an 8-bit operation code (opcode). The operation code part specified both an operation and a register. The instruction’s 12-bit address part usually specified an operand by giving the memory address of the memory word involved in the operation. Basic operations like load (copy a value from a memory word to the implied register), store (copy a value from the implied register to a memory word), add (add the value in a memory word to the value in the AC replacing the AC value with the sum) are referred to as memory-reference instructions and form the core instructions for both the IAS machine and the HCS08 microcontroller. When an instruction contains the actual full address of the operand, as the IAS memory-reference instructions did, the value is usually referred to as a direct address and those instructions are said to use the direct addressing mode. Unfortunately, Freescale’s terminology for the HCS08 refers to such instructions as extended addressing mode instructions, and uses direct addressing mode to mean something else. The IAS instruction set had only one other class of instructions which were called register-reference instructions. Such instructions were said to use the inherent addressing mode. The HCS08 also has many such instructions and also refers to them as inherent addressing mode instructions. It is almost an oxymoron to say these instructions have an addressing mode as they use no memory address at all. Such operations involved only the registers. An example of such an instruction for the IAS machine was to add the value in the MQ to the value in the AC replacing the value in the AC with the sum. At this point we should note that descriptions of computer instructions usually shorten the phrase “the value in the Register-name” to just “Register-name”. Thus we describe the above addition as adding MQ to AC. It is implied that we mean the value in or content of the registers, and that by adding “to” we are replacing the original value after it is used in the operation with the result of the operation. An example of a similar instruction in the HCS08 instruction set is the “mul” instruction. It means multiply X times A, where X and A are HCS08 registers, replacing the value in the X:A pair with the 16-bit product.
Normally, instructions are executed in the sequence they appear in memory with the instruction in Memory[i+1] being executed immediately following the execution of the instruction in Memory[i]. The CPU register that keeps track of where the next instruction is located is the PC. Its name come from the fact that it is an index into the Program and that its normal mode of being modified is to be incremented (so it Counts) after each instruction. On the IAS machine each instruction occupied only half a word so the PC was incremented after every other instruction. There was an additional Register bit that told whether the current instruction was in the first or last half of the word referenced by the PC. On the HCS08 instructions take from one to four memory words, so its PC may be incremented several times per instruction.
Branch (jump) Instruction
A different type of instruction from those that manipulate data is the branch (or jump) instruction. They are so named because they cause the CPU to deviate from the normal sequence of instructions. Instructions in this class change the value of the PC from its normal incrementing sequence by loading a new value into it in much the same way that the loading of other registers work. A big difference, however, is that branch and jump instructions usually come in both unconditional and conditional varieties. The unconditional ones always change the course of execution from the normal sequential order, the conditional ones, however, may change it or they may let the normal order continue. Which program path occurs usually depends on the outcome of some previous operation such as subtracting one value from another. The IAS’s conditional branch would change the normal sequence if the result of the most recent arithmetic operation were positive, otherwise it would let the normal sequence continue. Conditional branching is the feature that gives computers the power to perform complex algorithms. Without it they would only be able to perform simple formula-based calculations! The HCS08 has a rich assortment of conditional branch instructions. Conditional branching is the feature that gives computers the power to perform complex algorithms. Without it they would only be able to perform simple formula-based calculations! The HCS08 has a rich assortment of conditional branch instructions.
Data values in the IAS machine consisted of signed binary fixed-point numbers 40 bits in size. The sign used one bit so 39 bits remained to hold the magnitude of the value. The 39 bits are equivalent to about 12 decimal digits. As is true today, these fixed-point numbers could be considered to be integers or to contain fractional parts depending on where the binary point was considered to be. The hardware that performs calculations on the data works for a wide variety of conventions. Addition and subtraction require only that both operands are considered to have the binary point in the same position, there is no restriction on where it is considered to be. Multiply and divide don’t have even that restriction, but one must understand where the binary point of the results must be considered to be. Experimentation with decimal numbers with varying number of digits following the decimal point will allow one to understand the outcomes, and formulate the rules for properly placing binary points for the various computer operations. It should be made perfectly clear that no bits are used to indicate where the binary point is located; its position only exists in the way the programmer intends to interpret the value represented by the bits in the data word. Addition and subtraction instructions in the HCS08 support 8-bit unsigned and 2’s complement (signed) values. The multiply supports only 8-bit by 8-bit unsigned values – producing a 16-bit unsigned result. The divide instruction supports only a 16-bit by 8-bit unsigned divide, that produces an 8-bit quotient and a 8-bit remainder. By dividing the remainder by the original dividend, the quotient’s precision can be extended another 8 bits. This process can be repeated to any desired precision.
The first architectural improvement in computers that eliminated the need to have self-modifying code was indirect addressing. This addressing mode makes use of a pointer data type. A pointer is a word (or multiple words if a word is too small) that has a value used as an address to another word in the memory. To specify an address indirectly, the indirect addressing mode instruction contains the address of a pointer instead of the data. The CPU knows that for such instructions there must be two memory areas accessed. The first reads the pointer and then uses its value as the address to access (read or write) the actual operand. To change the memory location accessed by such an instruction, the instruction itself need not be modified, only the value of the pointer variable. Few computers still use this form of indirect addressing, but rather its cousin, register addressing or a variation of it. In register addressing, the pointer value must be loaded into an address register with one instruction, and then that address used with another instruction. Again, to modify the actual data location a register addressing mode instruction accesses, one need only modify the value in the address register. The HCS08 has two such address registers, H:X and SP, although the SP main use is as a stack pointer. A variety of addressing modes based on those two registers are available.
Modern desktop computers now have many registers that can be used as accumulators and/or address registers. It is not uncommon for a computer to have 32 32-bit general- purpose registers that can be used for either. The HCS08 has only a microprocessor as its computing core, so it has only a single 8-bit accumulator and a pair of 16-bit index (address) registers – no general-purpose registers. In order to program in machine language assembly language or you must first learn the architecture of the computer you plan to program. The architecture of a computer specifies the registers in the CPU, the main memory size, and the instruction set (including not only the operations it can perform, but also all the addressing modes supported).
We are ready to study the architecture of the HCS08 microcontroller’s microprocessor core. The general design is given below. It is only a slight modification of the IAS one shown earlier. The only difference is that the Input/Output (I/O) devices are memory-mapped devices. That is, you access them as though they were normal memory, with load and store instructions within the main memory address space.
There are big differences with the details of the design. The register set is different, the memory size and shape are different, and the instruction set contains many more instructions. However, the basic functioning of the machines is very much the same. They both have the same load/store nature where most ALU operations must be performed on values in the CPU’s registers. They are both single address machines in that at most one of the operands of binary (two operand) operations (such as add) can come from main memory. (Actually the HCS08 has a very limited set of “move” instructions that transfer data from one memory location to another without going through a register.) The main memory can contain both instructions and data at virtually any location (even intermixed – although we will try not to do that). The CPU can operate on instructions as though they were data.
Let’s check out the differences. The main memory of the IAS held 4096 40-bit values. The memory space of the HCS08 provides for 65536 8-bit values. Thus the HCS08 memory system uses a 16-bit address bus (216 = 65536) and an 8-bit data bus. The address bus carries information only one direction, to the memory system, but the data bus can carry information either to or from the memory (thus the double arrowheads on the data bus above). Not shown in the above diagram are control signals that tell the memory such things as whether a read or write is being performed. Each of the 65536 memory locations should be thought of as having an address and a contents (or value). The address is a 16-bit (4-hexadecimal-digit) number, while the contents is an 8-bit (2-hexadecimal digit) number. When we look at the instruction format we will find it is convenient that the value of an address can be stored exactly in two words of memory. In truth, that ability is the cause of the memory space being the size that it is.
At the risk of being too remedial, I will emphasize a possibly painfully obvious, but extremely important, concept. We often show the content of a section of memory by listing the memory address in one column and its content in another. Consider the example below. The left pair are in binary and the right in hexadecimal.
First, note how much more compact the hexadecimal (we’ll shorten that name as well, and start calling it hex) notation is. From this point on we will use mostly hex notation for address and values.
The key point I want to make is that only the value part is stored anywhere. The address is a fleeting number generated one at a time as needed and then its value disappears. When a program is being executed the Program Counter (PC) provides that value for instruction fetch. After each use of the PC it is incremented so the previous address value does not exist anywhere any more. The new value will exist only while it is being used to read the next word of the program.
Because the addresses are consecutive over an area of interest we often will show only the lowest address with a set of data values. By convention know that each successive memory content value is at an address that is one greater than the previous content. Thus the above set of memory values could be given as:
020D: 5B D8 74 06 31
A colon is often used to separate the address from a sequence of data values for added clarity. Here is my last restatement of the (hopefully blatantly obvious) address/data relationship – whenever the contents of locations 020D-0211 are given, the address part can never change, only the content can.
The HCS08 instruction set supports one 16-bit load operation. As 16-bit values require 2 words of memory, and the instructions specify only a single address, a convention must be established as to which of the two memory addresses that contain the 16-bit value will be specified in the instruction. It must also be decided whether the most-significant byte (MSB) or the least-significant byte (LSB) should be stored in the lower-numbered address of the pair. For me, this last question has an obviously best answer. Place the MSB at lower-numbered addresses. This convention is known as big-endian memory organization. When consecutive address values are written horizontally, the MSB will be to the left. This follows the standard convention for decimal numbers where more-significant digits appear to the left of less-significant digits. This convention, that more-significant bytes of multi-byte value be stored at lower address values, will never be violated in this course. In every situation that the HCS08 hardware dictates how they will appear, that convention is adhered to. In every situation where the programmer must decide, I will require that this rule be followed as well. Some machine designs even specify that two-byte values must start on an even address. Such requirements are referred to as memory alignment restrictions, but the HCS08 has no such restriction. The HCS08 always uses the address of the MSB, which is the lower of the pair. We will adopt that same convention, using the lowest address as the “handle”, for any program-defined groups of bytes for any size group that we create.
Registers to know
The Registers that you may need to know the most about are the ones in the Programmer’s Model as shown on Page 86 of the MC9S08QG Data Sheet for HCS08 Microcontrollers that is available in pdf form on the web and distributed in booklet form in class compliments of Freescale. The A register is an 8-bit accumulator used primarily for 8-bit arithmetic and load/store style moving of data. The H:X and SP register are used primarily for addressing. They are 16-bit registers so can point to any location in the memory space. The stack pointer (SP) exists primarily to support stack operations built into the hardware – we will learn all about these operations later. It is a 16-bit register as the stack utilizes main memory, and a 16-bit value allows the stack data to be placed anywhere in the memory space. The program counter (PC) tells where in the memory the next instruction to be executed is located. It is a 16-bit register so that instructions can exist and be executed out of any location in the memory space. The condition code register (CCR) keeps machine state information – our main programming use of it will be to guide conditional branch execution along the two paths that such instructions can direct a program. It is an 8-bit register.
This was wordy and didn’t necessarily wrap up completely but we have learned a lot of new information! I hope you enjoyed this article about the history of computer technology and how this introduces you to how a simple computer called a microcontroller works.