ECEN 2220 Textbook
The text for ECEN2220 is
the second edition of
Microcomputer Systems: The 8086/8088 Family,
by Yu-Cheng Liu and Glenn A. Gibson.
It was published in 1986 by Prentice-Hall, and its ISBN is 0-13-580499-X.
Why the 8086?
Why are we using the 8086, a machine that was superseded years ago?
Remember that
our aim in this course
is to position you to make use of whatever processor is appropriate for
your application at the time you are designing a system.
We can only reach that objective by teaching you general principles;
the intricate details of the latest processor will be rendered obsolete by
technical innovation before you graduate!
When attempting to teach general principles, it is best to present them in
as simple a setting as possible in order to avoid obscuring them in a
welter of irrelevant detail.
Although the setting should be simple, it should not be so simple that one
cannot demonstrate mastery of the principles by constructing working
systems.
Because the progression from the 8086 to its successors has preserved
backwards compatibility, it is possible to develop systems in the 8086
setting and still run those systems on modern personal computers.
Why this text?
Liu and Gibson provide an encyclopedic treatment of the 8086 and its major
supporting chips.
They explain all of the central processor instructions and the assembly
language in which algorithms can be constructed using those instructions.
They describe the important I/O interfaces in detail, giving sample
programs to manipulate them.
General principles of programming methodology and concurrency control
are also mentioned and illustrated.
Unfortunately, an encyclopedic treatment of a single system usually does not
provide the best exposition of basic principles because
the presentation order and attention to detail obscures the important
points that transcend the particular system.
Nevertheless, the attention to detail is vital if one actually wants to
tests one's understanding by building working systems.
We believe that this text represents the best compromise available, and
that it meets the needs of the course.
In order to get the most out of the text, you must use it in an appropriate
manner.
Don't try to read it cover-to-cover and master all of the details.
Read it along with the lectures and homework, adjusting your goals
according to the task at hand.
For example, when you are writing a procedure and trying to understand
the addressing mode you should use to access an argument passed on the
stack, you need to pay attention to all of the details.
On the other hand, when you are reviewing for
examinations
you need to understand the level of detail that we expect you to master.
(The notes given in the next section give a partial answer to that question,
and previous exams are also available.)
How does the text relate to the lectures?
This section gives an overview of the text, linking the topics in each
section to the
course syllabus.
It also indicates what you should try to learn from each of the sections,
characterizing the level of detail that is important for this course.
Certain sections of the book do not appear in the syllabus.
For each of those sections, we include a brief explanation here of why that
section was omitted.
-
To
set the stage
for any discussion of computers as components,
it is important to understand the architecture of the computer subsystem:
how the processor that implements the decision making is connected to the
interfaces that enable it to interact with its environment,
how information is represented within that processor,
and how that processor operates on that information.
On a first reading of this chapter you should try to get the big picture of
the system.
As you work with various aspects during the semester, the details will
become second nature without further effort on your part.
However, when new areas are introduced or when you need to get out of the
trees to see the forest, come back to Chapter 1.
Section 1-2-3 is revisited in the discussion of
serial input/output because it shows how
ASCII characters appear as sequences of bits on a serial line, and
Section 1-3 provides support for
the treatment of
addressing modes.
-
-
The architecture of the CPU includes its register configuration,
the way in which it accesses memory,
and the way in which it represents its internal state.
These are all
fundamental properties
that any user must be familiar with.
The material on memory organization describes the memory access that takes
place once an effective address has been calculated by an
addressing mode.
-
The basic
execution time
or understand the detailed interaction between the central processor and a
coprocessor.
-
Machine language instructions generally have two parts,
an operation code, which describes what the instruction should do,
and operands, which describe the data.
Operands may describe data in the instruction stream itself, in registers,
or in memory.
A particular processor makes available a fixed number of ways to describe
data, called
addressing modes.
It is impossible to write any program at all for a processor without
understanding addressing modes, because without this understanding you
cannot formulate instructions.
The instructions of the 8086 are represented as compactly as possible, in
order to reduce the number of memory fetches required for instructions.
Details of this compact representation are not interesting except as
explanations of certain restrictions on addressing modes, unless
one is trying to precisely determine the
execution time
of a code fragment.
-
It is generally not useful to try to determine the execution time of a
program of any size on the basis of the execution times of its individual
instructions.
This only becomes feasible for short code fragments in
particular situations.
-
The differences between the 8086 and 8088 are only of interest to a person
using the 8088 in a system.
-
Detailed descriptions of the commonly-used instructions can be found in
this chapter.
There will be no attempt in lecture to reproduce these descriptions,
nor will you be expected to regurgitate them on examinations.
Many of the instructions will be used in examples given in lectures, and
you will use those and others in the course of implementing code for
homework assignments.
The best way to use this chapter is to read a section carefully when you
have need of the instructions it describes, and then to use it as necessary
for reference when you study examples or write code.
Each of the sections below is cross-referenced to the lecture topic that
first uses the instructions it describes.
Instruction use is cumulative, however, so you can expect the instructions
to be used again in later lectures.
-
A single general format is used for all assembler language instructions.
This format will be used to
describe instructions
in all contexts, not only when they appear in programs.
-
As their name implies, data transfer instructions move information from one
place to another.
They are used to illustrate the
basic properties of the machine.
-
Integer arithmetic is also a basic operation, without which very little
is possible.
In this course we are concerned only with
binary arithmetic, which is covered in
Section 3.3.1.
You will be responsible for the details of 2's complement addition and
subtraction, including the behavior of the carry and borrow indicators,
and for the use of the AX and DX registers by the multiplication and
division instructions.
Although BCD arithmetic is interesting in some contexts, notably in
business applications, it is not relevant for this course.
You will therefore not be responsible for BCD arithmetic in any form,
and may totally ignore Sections 3-3-2 and 3-3-3.
-
Branch instructions allow a program to make
decisions, and are used to implement the
conditional and iterative constructs of higher-level programming languages.
They appear in virtually any program.
-
The 8086 has special instructions for implementing certain iterations
efficiently.
They are introduced in the context of a
procedure
that moves arbitrary information from one area of memory to another.
-
The use of the NOP instruction proposed in the text constitutes poor
programming practice, and the HLT instruction is not useful in a system
that is interacting with its environment.
We therefore omit this section.
-
The flags form part of the state of the central processor, and these
instructions allow the program to operate on that state.
They are introduced in the context of a
procedure
that moves arbitrary information from one area of memory to another,
and also figure prominently in software conversions between integer and
floating-point representations.
-
Data often consists of a number of single-bit values occupying the
individual bits of a byte.
Logical instructions are used to insert bit values into larger units and
extract them again.
They are introduced in the context of
serial input/output operations,
and also figure prominently in software conversions between integer and
floating-point representations.
-
These instructions reposition data within a byte or word.
They are introduced in the context of software conversions between integer
and
floating-point representations.
-
Not all components of assembler language programs are instructions.
There are also directives that allow one to describe
storage layouts
and provide other information to the assembler.
-
The nature of the
assembly process
results in certain restrictions on assembly code programs,
and an understanding of the process helps in
understanding and avoiding those restrictions.
-
This section is really a table, giving the translation of every 8086
instruction.
It is primarily useful as an aid in understanding the
problems faced by the assembler
when translating a program.
-
Modular decomposition is the programmer's primary tool for controlling
complexity.
-
Separately-written modules must be
combined for execution
by a linker.
Symbols used in one module but defined in another must be specified to this
program, as must the segments making up each module and the way in which
they are to be combined.
You are responsible for understanding the directives that communicate this
information and the types of segment combination that are possible.
You do not, however, need to know the precise mnemonics involved.
-
Stacks are used for
temporary storage
and for argument values and local variables in
procedures.
You are responsible for understanding the operation of the stack instructions
and the direction of stack growth.
-
Procedures are the simplest form of module.
They are characterized by an interface specification, which acts
as a contract between the implementor and the user.
Certain parts of that specification are implicit and others explicit.
The implicit parts must be fixed by convention, usually uniform over all of
the languages on a particular machine.
You are responsible for understanding the behavior of the procedure call
and return instructions, and for the conventions used in 8086 procedure
calls.
-
An
interrupt
is a mechanism for shifting the central processor's attention
from one task to another asynchronously, like the sound of a telephone bell
shifts a person's attention.
Vectoring, state preservation, enabling and disabling are important
concepts in any interrupt system and you are responsible for those
concepts.
You are not, however, responsible for details like the stack layout or the
locations of specific interrupt vectors.
-
A macro facility provides assembly-time procedures, which are very useful
for constructing large programs or programs that must be quite flexible.
In our application, however, we are using assembly code for very specific
purposes and small routines.
Thus macros are not relevant to our application and we omit this section.
-
We assume that the elementary programming class that is a prerequisite for
ECEN 2930 has provided students with an understanding of programming
methodology at least equal to that given here.
Thus we omit this section.
-
The example in this section involves a business application that is
irrelevant to ECEN 2220, and is thus omitted.
-
-
The string instructions first appear in the procedure to
move a block of storage,
the example used to illustrate procedure calling conventions.
You are responsible for the general concept of string instructions,
including their side effects on registers, but not the specific set of
instructions available.
-
The REP prefix first appears in the procedure to
move a block of storage,
the example used to illustrate procedure calling conventions.
You are responsible for understanding that the REP prefix provides
controlled iteration of a single instruction, but not the details of the
terminating conditions.
-
This example is not relevant to the goals of this course, and is therefore
omitted.
-
The table translation instruction first appears in the procedure to
print numbers,
the example used to illustrate recursive procedures.
You are responsible for knowing that there is a special instruction useful
for character translation, but not the details of its operation.
-
Number format conversion is illustrated by a procedure to
print numbers.
You are responsible for the general conversion algorithm, which you should
be able to write in any programming language, and whose operation
you should be able to explain to a novice.
-
-
The IN and OUT instructions first appear when we interact with the
serial I/O interface.
You are responsible for knowing how port addresses are specified to these
instructions, and how they interact with the accumulator.
You are not responsible for the instruction coding.
-
Since I/O operations are generally much slower than central processor
operations, the central processor must be careful not to overload the I/O
devices.
The devices have flags indicating their status, and the central processor
can determine when an I/O device is ready to accept more work by
polling those flags.
You should be able to explain to a novice what states are possible for a
device like the universal asynchronous receiver/transmitter (UART), and how
the central processor should poll and react to those states.
You are not responsible for the coding of the states.
-
By using interrupts to catch the attention of the central processor when the
status of an I/O device changes, we can avoid the time needed to poll that
device's status.
Thus the central processor is free to carry out computations while the I/O
device is interacting with the environment, allowing the two tasks to
proceed in parallel.
You should be able to explain this concept to a novice, relating it to
examples from daily life.
Interrupt control of I/O devices involves
stylized algorithms
that change very little from one machine architecture to another.
You should understand the structure of these algorithms and the purpose of
each part, but you are not responsible for detailed coding.
Double buffering is a special case of the more general
buffer management problem.
You should understand the need for multiple buffers, but you are not
responsible for the specific algorithms appearing in this section.
The principle of daisy chaining, that devices can be arranged in a physical
order such that specific devices take precedence over others is important,
but you are not responsible for the logic by which this is implemented.
You should also understand the concept of a priority interrupt: why it is
useful and how interrupt service routines must
manipulate IF to make priority interrupts effective.
You are not responsible for the details of the priority interrupt
controller.
-
Some devices transmit information
faster than the central processor can deal with
it.
Of course if the overall data rate is too high then a faster central
processor is required, but if the data comes in bursts (as from a disk)
then a
separate processor
can be used to service the device and store the information in memory for
later perusal.
Such processors use direct memory access (DMA), bypassing the central
processor, to store information.
You should understand DMA as a manifestation of the
underlying architecture of the machine,
and how the various components interact.
You should be able to draw a rough picture showing the relationships among
the components, similar to Figure 6.16.
The sequence of events is important, and you are responsible for
knowing that sequence.
You are not, however, responsible for the detailed structure of the DMA
controller or the device interface.
-
This example is used as an illustration of the use of
multiple buffering.
You are responsible for the concept of multiple buffering, why it is
necessary and when it should be used, but not the details of the scheme
described in this section.
A more general implementation of multiple buffering
(called a circular buffer),
which subsumes both this example and the one discussed in
Section 6-3,
will be presented in lecture.
You are responsible for the characteristics and use of circular buffers,
but not of the more restricted buffering schemes appearing here.
-
-
The important points here are the concept of a
process state (sleeping,
awake, etc.) and the representation of processes by process control blocks.
You should understand how a process can be moved from one state to another
by events, but you are not responsible for the details of process
representation in iRMX 86.
-
Cooperating sequential processes
are used to carry out tasks that are largely independent, but must
sometimes exchange information.
Synchronization of these exchanges is a very difficult thing to get right.
Semaphores provide one low-level mechanism that can be implemented on most
machines.
Correct implementation of semaphores demands a good understanding of the
hardware being used as well as of the ways in which such synchronization
can go awry.
You are responsible for the conceptual operation of a semaphore, and the
hardware properties of the 8086 that make semaphores possible.
You should be able to state the assumptions about underlying hardware that
must be met if cooperating sequential processes are to be implemented,
and point out some implementations that are incorrect even under these
assumptions.
-
When a number of tasks share code, that code must be written in a stylized
manner so that the tasks do not interfere with one another.
You should be able to state the conditions under which 8086 procedures are
reentrant,
and how the hardware supports the construction of pure code.
-
When the central processor is executing a particular process, that process
occupies a portion of the memory.
The system needs to manage its memory resources so that memory will be
available when processes need it, and so that processes cannot interfere
with portions of memory that are not supposed to be accessible to them.
You should understand the common
problems encountered in managing memory,
and the strategies employed to solve them.
-
The 80286
memory management hardware
is typical of the use of segmentation.
You should be able to explain its general characteristics, and also those
of the base and limit addressing and paging strategies via diagrams and
narrative.
Given a specific memory size, you should be able to come up with
appropriate page and segment sizes and specify the necessary registers.
You are not responsible, however, for the specifics of the 80286.
-
-
In a complex system the central processor must provide
information
about its internal state to other processors with which it is cooperating,
and vice-versa.
The ways in which this information is conveyed depends upon the complexity
of the system.
You are not responsible for the details of the bus that support such
information, but you should understand the kinds of information that are
important and be able to explain how that information is used.
-
The system bus timing affects the ways in which components of that system
can interact.
You should understand the major uses of the
bus,
and how these share the bus over time.
Although you need not be able to regurgitate the detailed timing diagrams,
you should be able to read diagrams given in the text's notation and
explain their meaning.
-
The important material in this section is the discussion of the
interactions among
interrupt handlers
at different priority levels.
You are not responsible for the details of the interrupt priority controller
itself, although you should have an idea of its capabilities.
-
Bus standards are necessary if a variety of
processors are to communicate using a bus.
You should know the kinds of information that need to be standardized, and
why standards must be provided for exactly that information.
You are not responsible for the particular characteristics of the Multibus.
-
-
You are responsible only for the material in the introduction and
Section 9-1-1.
The remainder of the section will help you to understand the
device interface
when you are implementing the serial I/O drivers needed for some
of the homework assignments.
-
You are responsible only for the general properties of parallel interfaces
appearing in the introduction and Figure 9-20.
Section 9-2-1 will help you to understand the details of parallel
interfaces when you are using them to simulate asynchronous serial I/O in
one of the homework assignments.
Our laboratory setups do not use the parallel port to interface to analog
signals, and therefore Section 9-2-2 is largely irrelevant.
It does, however, give you a slightly different discussion of
how A/D and D/A converters work.
-
You are responsible only for the material in the introduction.
Our laboratory setup does not use the Intel 8254 chip, but the remainder
of the section may help you to understand the
device interface
when you are implementing programs that require timing information.
-
This section will be omitted because it provides a low-level treatment of a
topic that is not particularly relevant to the goals of ECEN 2220.
-
You are responsible only for the
general outline of a DMA controller
shown in Figure 9-36, not the details of the 8237.
The details may, however, help you to understand the
sequence of operations involved in a DMA transfer,
which you are responsible for.
-
This section will be omitted because it provides a low-level treatment of a
topic that is not particularly relevant to the goals of ECEN 2220.
-
This section will be omitted because it provides a low-level treatment of a
topic that is not particularly relevant to the goals of ECEN 2220.
-
The details of memory implementation are not relevant for the goals of this
course, and thus we will omit this chapter.
-
-
Queue status allows other processors to understand how a central processor
is using the bus to obtain instructions.
It is needed during
coprocessor interaction, where another
processor is also interpreting parts of instructions.
A LOCK prefix is used to extend the
assumptions
about indivisible memory access that are needed for
cooperating sequential processes
to cover actions by other processors.
You are responsible for the principles involved in both the export of queue
status and use of the lock prefix, but you are not responsible for the
actual queue state encodings.
-
You are responsible for the general principles of
coprocessor and
closely coupled configurations, including the ways in which the central
processor and coprocessor use the instruction stream and the ways in which
processors wake each other up.
The configurations shown in Figures 11-5, 11-7 and 11-8 will help you to
understand what's going on, but you will not be expected to reproduce them.
We will omit Sections 11-2-3 and 11-2-4.
-
Software manipulation of
Floating-point numbers
is very time-consuming, but this representation is critical for programs
handling data that model continuous functions in the real world.
The floating-point coprocessor is a hardware implementation of the
basic floating-point algorithms.
It interacts very closely with the central processor, sharing the same
instruction stream yet operating independently.
You are responsible for the architecture of the 8087 as seen by the
programmer: stack, conditions, and operations.
The detailed diagrams and instruction encoding is not important, although
you do need to understand the way coprocessor instructions are organized
(recall Section 11-2-1).
-
The details of this processor are irrelevant to us, and hence we omit this
section.
Use it as a reference if necessary to help you understand the interaction
of closely coupled processors described in
Section 11-2-2.
VLSI Processing and Supporting Devices
More complex devices that take over more of the common tasks of a central
processor are useful components of increasingly complex systems.
They do not introduce any new principles, however, and therefore they can
be mastered at the time a need for them is encountered.
The 80286/80287
The 80286 is a later version of the processor that we have studied in this
course, and the 80287 is its numeric coprocessor.
These chips have themselves been superseded by later models of increased
capability.
There is no point in our studying these chips:
the increased complexity does not introduce any new principles, and
the pace of technological innovation makes it unlikely that you will
actually use them in a specific project.