I’ve presented here, but the general outlines (and even a decent number of the specifics) are the same.
The Clock
Steps 1 through 12 in the previous section don’t take an arbitrary amount of
time to complete. Rather, they’re performed according to the pulse of the
clock that governs every action the processor takes.
This clock pulse, which is generated by a clock generator module on the
motherboard and is fed into the processor from the outside, times the func-
tioning of the processor so that, on the DLW-1 at least, all three steps of the
fetch-execute loop are completed in exactly one beat of the clock. Thus, the
The Mechanics of Program Execution
29
program in Figure 2-9, as I’ve traced its execution in the preceding section,
takes exactly four clock beats to finish execution, because a new instruction is fetched on each beat of the clock.
One obvious way to speed up the execution of programs on the DLW-1
would be to speed up its clock generator so that each step takes less time to
complete. This is generally true of all microprocessors, hence the race among
microprocessor designers to build and market chips with ever-higher clock
speeds. (We’ll talk more about the relationship between clock speed and
performance in Chapter 3.)
Branch Instructions
As I’ve presented it so far, the processor moves through each line in a pro-
gram in sequence until it reaches the end of the program, at which point the
program’s output is available to the user.
There are certain instructions in the instruction stream, however, that
allow the processor to jump to a program line that is out of sequence. For
instance, by inserting a branch instruction into line 5 of a program, we could cause the processor’s control unit to jump all the way down to line 20 and
begin executing there (a forward branch ), or we could cause it to jump back up to line 1 (a backward branch ). Because a program is an ordered sequence of instructions, by including forward and backward branch instructions, we
can arbitrarily move about in the program. This is a powerful ability, and
branches are an essential part of computing.
Rather than thinking about forward or backward branches, it’s more
useful for our present purposes to categorize all branches as being one of the
following two types: conditional branches or unconditional branches.
Unconditional Branch
An unconditional branch instruction consists of two parts: the branch instruction and the target address.
jump #target
For an unconditional branch, #target can be either an immediate value,
like #12, or an address stored in a register, like #D.
Unconditional branches are fairly easy to execute, since all that the com-
puter needs to do upon decoding such a branch in the instruction register is
to have the control unit replace the address currently in the program counter
with branch’s target address. Then the next time the processor goes to fetch
the instruction at the address given by the program counter, it’ll fetch the
address at the branch target instead.
Conditional Branch
Though it has the same basic instruction format as the unconditional
branch (instruction #target), the conditional branch instruction is a
30
Chapter 2
little more complicated, because it involves jumping to the target
address only if a certain condition is met.
For example, say we want to jump to a new line of the program only if
the previous arithmetic instruction’s result is zero; if the result is nonzero,
we want to continue executing normally. We would use a conditional
branch instruction that first checks to see if the previously executed
arithmetic instruction yielded a zero result, and then writes the branch
target into the program counter if it did.
Because of such conditional jumps, we need a special register or set
of registers in which to store information about the results of arithmetic
instructions—information such as whether the previous result was