From our perspective in today's lecture, a computer has three important components: some memory, a CPU, and a bus that connects them (this quite deliberately leaves out the whole input/output system, which we'll be dealing with extensively later. But it isn't important today).
Let's think about a couple of lines of code from a program, written in a high level programming language:
i = 3;
j = i + 4;
If we think about, we've got two different "kinds" of things here:
we've got the variables we want to manipulate (i and
j), and we've got the code for the operations we want to
perform on them (set i to 1, add
2 to it and set j to that new value). This
(the variables and the code) is what goes in the memory. As
we'll see in a moment, so far as the computer is concerned both the
variables and the code are just numbers.
You can put numbers into memory, and you can take numbers out of it. The memory is organized so that every location has an address: so we have memory location 0, location 1, location 2, location 3, and so forth. You can think of it like an array; you can assign values to locations in the array, and get values out of locations in the array. Here's a figure showing the memory:
If you've come across hexadecimal arithmetic before, you've already
noticed that I've written the numbers in the memory as hexadecimal.
The $ in front of each one is how we will tell the
assembler that we want to use a hexadecimal number. If you haven't
seen hexadecimal numbers before, don't worry about it: you will soon!
The HC11 actually has two types of memory on it: RAM (Random Access Memory), which we can read or write, and EEPROM (Electrically Eraseable Programmable Read Only Memory), which we can read but we can't write, and which doesn't "forget" its contents when we turn off the computer. Variables have to go in RAM, and the program has to go in EEPROM.
The other thing we need to execute a program is something to do the executing. This part is called the Central Processing Unit, or CPU.
The main things the CPU contains are:
We need to have memory actually in the CPU because getting it from "memory" takes too long (one of the major determiners of how powerful a computer is, is how many registers it has in the CPU, and how much can be transferred at a time between memory and the CPU); one of the most effective ways to make a program run faster is to make sure you have the most-used data present in the CPU at all times.
We'll be introducing the registers a few at a time, as needed. For today, we need the Program Counter, the Instruction Register, and the A Accumulator.The PC always contains the address of the next instruction to be executed. A is a register where we "accumulate" results. The IR is a register that's used internally by the CPU to keep track of what it's doing; we don't directly manipulate it.
So, here's a picture of the computer as we're looking at it today.
Let's take a look at a fragment of code in memory (this fragment is taken from a program you can find at http://www.cs.nmsu.edu/~pfeiffer/classes/273/notes/inst-execution.lst. Suppose we have
$f800: $86
$f801: $03
$f802: $97
$f803: $00
Also, let's suppose that before we start, the PC contains
$f800. So here's what things look like before we start:
(of course, the IR and Accumulator A actually contain something. We just don't know what, and their initial contents won't be relevant to the example)
$f800, getting the value
$86 back. This is the instruction fetch,
and the number we just read from memory is called the instruction's
opcode (that's short for "operation code"). We put
$86 in the instruction register so we can work
with it, and simultaneously add 1 to the PC so it now
contains $f801. This step is the same for
every instruction.
$86 means. To do this, we need to
turn to the Reference Guide, Page 8.
We look in column 8, row 6 (since those are the two digits in the
opcode). When we do this, we find a large box in the table, marked
LDA. That's the instructions name, which is short for
Load Accumulator. Notice that all of
the columns from $8 through $f, and row
$6, are Load Accumulator (LDA) instructions.
We can also find more information here: we also find that all of
the columns from $8 through $b, regardless
of row, are headed by ACCA. This tells us that all
of these instructions (including the one we're interested in) affect
Accumulator A. Finally, column $8 itself is headed by
IMM. This tells us that we're using immediate
addressing.
Putting all this information together, we're executing a Load Accumulator instruction, using Accumulator A, and Immediate Addressing. This figuring out what the instruction is, is called the instruction decode. This step is also the same for every instruction (though, of course, we get a different answer depending on what the instruction is).
LDA instruction appears
on page 551.
This gives a complete specification of the instruction: first,
Operation tells us what it does — with a little help from
the nomenclature guide on pages 488 and 489, we see that the contents
of a memory location are copied into either Accumulator A or
Accumulator B. The Description: says the same thing, in
something more like English. We'll ignore the Condition Codes
for the moment, and turn to the tables at the bottom, where we see
that LDAA (IMM) performs the following steps:
$86. Of course, we already knew that; it's
how we started! Something that's implicit here is that every
time we read from the address pointed to by the PC, the PC is
incremented (like we said before). So now it contains
$f801.
ii means) from
OP + 1 — in other words, the
address the PC is now pointing to. After we've read it, we
increment the PC again, so it now contains $f802.
From the definition of the operation of the instruction, we know
that the value read in the second cycle is loaded into the A
Accumulator. The result is that
Acc A = $03.
All this stuff after the instruction decode is instruction execution. This is different for every instruction.
Here's what things look like now:
Now we're ready to go to the second instruction.
$f802, getting an opcode of $97 this time.
$f803.
STA, using accumulator A and
direct addressing.
STAA.
A => M,
is a more formal description of the instruction.
A DIR.
$97. Of course, we already knew that.
dd.
The nomenclature table for the reference guide is on page 20;
we see that dd means one byte of
direct address.
$00.So here's what things look like now:
Now let's take a look at the code implementing j = i +
4;. Here it is:
$f804: $96
$f805: $00
$f806: $8b
$f807: $04
$f808: $97
$f809: $01
See if you can decode and hand-execute this code.