Download UNIT II INTRODUCTION TO 8086 MICROPROCESSOR 2.1

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
UNIT II
INTRODUCTION TO 8086 MICROPROCESSOR
2.1 Introduction
The Intel 8086 is a 16-bit microprocessor that is intended to be used as the CPU
in a microcomputer. 16-bit indicates that the word length of the microprocessor.
The 8086 microprocessor has a 16-bit data bus and hence it’s ALU and internal
registers are able to process 16 bits of information at a time. To speed up the
processing, 8086 divides the work to be done into two functional units namely
Execution Unit (EU) and Bus Interface Unit (BIU). The BIU is responsible for the
transfer of data and addresses on the buses for the EU. The EU instructs the BIU
to fetch the instructions or data from the memory, decodes the instructions and
executes instructions. The 8086 microprocessor produces the physical address
by adding the effective address to the contents of any one of the four segment
registers and this way of addressing the memory is called segment:offset
notation. The effective address of the operands can be calculated in different
ways and hence effective address calculation leads to different addressing
modes. To program 8086 and to develop 8086 based systems it is necessary to
study about the instruction set of 8086. Overall, this unit makes you to learn the
architecture, memory addressing and instruction set of 8086 microprocessor.
2.2 Learning Objectives





To study about the architecture of 8086
To study about the segment registers and memory addressing of 8086
To learn the various addressing modes supported by 8086
To study the various types of instructions provided by 8086
To study the pin diagram and the signals of various pins of 8086
2.3 8086 Architecture
The architecture of 8086 includes Arithmetic Logic Unit (ALU), flags, general
registers, instruction byte queue and segment registers. The 8086 CPU logic has
been partitioned into two functional units namely Bus Interface Unit (BIU) and
Execution Unit (EU) as shown in figure 2.1. The major reason for this separation
is to increase the processing speed of the processor. You please observe that
this separation and the increase in the word length improve the performance of
8086 in comparison with that of 8085. These two units cooperate
asynchronously. The BIU has to interact with memory and input and output
devices in fetching the instructions and data required by the EU and in sending
the results produced by EU to the memory or the output device. As the name
implies, the EU is responsible for executing the instructions of the programs and
to carry out the required processing. EU gives the instructions to the BIU to
decide where to fetch instructions or data from and where to send the result. In
1
addition to giving the instructions to the BIU, EU decodes instructions and
executes instructions.
Figure 2.1 Functional Components of 8086 Architecture
Detailed view of 8086 architecture is shown in figure 2.2.
2
Figure 2.2 Detailed Architecture of 8086 Microprocessor
2.3.1 The Execution Unit (EU)
The Execution Unit (EU) of 8086 microprocessor has control unit, instruction
decoder, Arithmetic and Logical Unit (ALU), general registers, flag register,
pointers and index registers.
Control unit is responsible for the co-ordination of all other units of the processor.
It generates timing and control signals which are necessary for the execution of
instructions. It controls the data flow between CPU and peripherals (including
memory). It provides status, control and timing signals which are required for the
operation of memory and I/O devices. It directs the internal operations of the
processor. In short, we can say that it controls the entire operations of the
microprocessor and peripherals connected to the microprocessor. Hence you
can understand that control unit is like the brain of an 8086 based microcomputer
system.
The EU of 8086 has a 16-bit ALU. ALU performs various arithmetic and logical
operations over the data. It takes care of all manipulations required over the data
to produce the required output. Some frequently performed operations are
addition, subtraction, logical AND, logical OR, logical XOR, complement, left
shift, right shift etc.
The instruction decoder translates the instructions fetched from the memory into
a series of actions that are carried out by the EU. Instruction decoding is the
process of segregating the instruction into opcode and operands.
Registers
Various registers present in the EU can be divided into three categories namely
general registers, flag register and pointers and index register.
General Registers
General registers are used for temporary storage and manipulation of data and
instructions. Data remain in the registers till they are sent to the memory or I/O
devices. The various general registers are shown in figure 2.3.
Accumulator register consists of two 8-bit registers AL and AH, which can be
combined together and used as a 16-bit register AX. AL in this case contains the
low-order byte of the word, and AH contains the high-order byte. Accumulator
can be used for I/O operations and string manipulation.
3
Base register consists of two 8-bit registers BL and BH, which can be combined
together and used as a 16-bit register BX. BL in this case contains the low-order
byte of the word, and BH contains the high-order byte. BX register usually
contains a data pointer used for based, based indexed or register indirect
addressing.
Count register consists of two 8-bit registers CL and CH, which can be combined
together and used as a 16-bit register CX. When combined, CL register contains
the low-order byte of the word, and CH contains the high-order byte. Count
register can be used as a counter in string manipulation and shift/rotate
instructions.
Data register consists of two 8-bit registers DL and DH, which can be combined
together and used as a 16-bit register DX. When combined, DL register contains
the low-order byte of the word, and DH contains the high-order byte. Data
register can be used as a port number in I/O operations. In integer 32-bit multiply
and divide instruction the DX register contains high-order word of the initial or
resulting number.
Figure 2.3 General Registers of 8086
Flag Register
This register is a 16-bit register containing a collection of 9 flags (each flag is a
flip flop) as shown in figure 2.4. Each of these flip flops holds 1-bit flag that
indicates certain conditions which arises during arithmetic and logic operations.
4
Figure 2.4 Flag Register of 8086
The meanings of each flag are shown below.
Overflow Flag (OF) - set if the result is too large positive number, or is too small
negative number to fit into destination operand.
Direction Flag (DF) - if set then string manipulation instructions will autodecrement index registers. If cleared then the index registers will be autoincremented.
Interrupt-enable Flag (IF) - setting this bit enables maskable interrupts.
Single-step Flag (TF) - if set then single-step interrupt will occur after the next
instruction.
Sign Flag (SF) - set if the most significant bit of the result is set.
Zero Flag (ZF) - set if the result is zero.
Auxiliary carry Flag (AF) - set if there was a carry from or borrow to bits 0-3 in the
AL register.
Parity Flag (PF) - set if parity (the number of "1" bits) in the low-order byte of the
result is even.
Carry Flag (CF) - set if there was a carry from or borrow to the most significant bit
during last result calculation.
Since flag register reflects the happenings inside the 8086 microprocessor, it is
called the Program Status Word (PSW). The contents of PSW, accumulator and
other registers are saved in the stack during the handling of interrupt. Flag
registers can be summarized as follows.
5
Pointers and Index registers
Pointer registers are used to point to a particular location either in memory or
stack from which the data is to be read or to which the data is to be written. Index
registers are useful in implementing sophisticated addressing modes (identifying
the location of the operands). The EU of 8086 has the set of pointers and index
registers as shown in figure 2.5. The functions of pointers and index registers are
explained as follows.
Stack Pointer (SP) is a 16-bit register pointing to program stack.
Base Pointer (BP) is a 16-bit register pointing to data in stack segment. BP
register is usually used for based, based indexed or register indirect addressing.
Source Index (SI) is a 16-bit register. SI is used for indexed, based indexed and
register indirect addressing, as well as a source data addresses in string
manipulation instructions.
Destination Index (DI) is a 16-bit register. DI is used for indexed, based indexed
and register indirect addressing, as well as a destination data addresses in string
manipulation instructions.
6
Figure 2.5 Pointers and Index registers of 8086
2.3.2 The Bus Interface Unit (BIU)
The BIU has an instruction stream byte queue, a set of segment registers and
instruction pointer.
Instruction Byte Queue
8086 instructions vary from 1 to 6 bytes. Therefore fetch and execution are taking
place concurrently in order to improve the performance of the microprocessor.
The BIU feeds the instruction stream to the execution unit through a 6 byte
prefetch queue. This prefetch queue can be considered as a form of loosely
coupled pipelining. Execution and decoding of certain instructions do not require
the use of buses. While such instructions are executed, the BIU fetches up to six
instruction bytes for the following instructions (the subsequent instructions). The
BIU store these prefetched bytes in a first-in-first out register by name instruction
byte queue. When the EU is ready for its next instruction, it simply reads the
instruction byte(s) for the instruction from the queue in BIU. This process is much
faster since it forms a pipeline.
Segment Registers
In 8086, program, data and stack memories occupy the same memory space.
The total addressable memory size is 1MB KB. As the most of the processor
instructions use 16-bit pointers the processor can effectively address only 64 KB
of memory. To access memory outside of 64 KB the CPU uses special segment
registers to specify where the code, stack and data 64 KB segments are
positioned within 1 MB of memory.
Memory can be thought of as a vast collection of bytes. These bytes need to be
organized in some efficient manner in order to be of any use. A simple scheme
7
would be to order the bytes in a serial fashion and number them from 0 (or 1) to
the end of memory. The numbers thus given to the individual positions in
memory are called ADDRESSES. The problem with this approach is that towards
the end of memory, the addresses become very large. For example, if a
computer has 1 Megabyte of RAM, the highest address would be 1048575
(=1024*1024-1). This definitely would not fit in a 16-bit register and therefore
addresses need to be stored in two registers. The scheme used in the 8086 is
called segmentation. Every address has two parts, a SEGMENT and an
OFFSET. The segment indicates the starting of a 64 kilobyte portion of memory,
in multiples of 16. The offset indicates the position within the 64k portion.
Absolute address = (segment * 16) + offset
The memory of 8086 is divided into 4 segments namely code segment (program
memory), data segment (data memory), stack memory (stack segment) and extra
memory (extra segment). The various segments of the memory and the
corresponding segment registers are shown in figure 2.6 and they are explained
as follows.
Program memory – Program can be located anywhere in memory. Jump and call
instructions can be used for short jumps within currently selected 64 KB code
segment, as well as for far jumps anywhere within 1 MB of memory. All
conditional jump instructions can be used to jump within approximately +127 - 127 bytes from current instruction.
Data memory – The processor can access data in any one out of 4 available
segments, which limits the size of accessible memory to 256 KB (if all four
segments point to different 64 KB blocks).
Stack memory – A stack is a section of the memory set aside to store addresses
and data while a subprogram executes. The stack segment register is used to
hold the upper 16 bits of the starting address for the program stack.
Extra segment – This segment is also similar to data memory where additional
data may be stored and maintained. This area is very often used for string
related operations.
Accessing data from the Data, Code, Stack or Extra segments can be usually
done by prefixing instructions with the DS:, CS:, SS: or ES: (some registers and
instructions by default may use the ES or SS segments instead of DS segment).
Word data can be located at odd or even byte boundaries. The processor uses
two memory accesses to read 16-bit word located at odd byte boundaries.
Reading word data from even byte boundaries requires only one memory
access.
8
Stack memory can be placed anywhere in memory. The stack can be located at
odd memory addresses, but it is not recommended for performance reasons.
Code Segment (CS) register is a 16-bit register containing address of 64 KB
segment with processor instructions. The processor uses CS segment for all
accesses to instructions referenced by instruction pointer (IP) register. CS
register cannot be changed directly. The CS register is automatically updated
during far jump, far call and far return instructions.
Stack Segment (SS) register is a 16-bit register containing address of 64KB
segment with program stack. By default, the processor assumes that all data
referenced by the stack pointer (SP) and base pointer (BP) registers is located in
the stack segment. SS register can be changed directly using POP instruction.
Data Segment (DS) register is a 16-bit register containing address of 64KB
segment with program data. By default, the processor assumes that all data
referenced by general registers (AX, BX, CX, DX) and index register (SI, DI) is
located in the data segment. DS register can be changed directly using POP and
LDS instructions.
Extra Segment (ES) register is a 16-bit register containing address of 64KB
segment, usually with program data. By default, the processor assumes that the
DI register references the ES segment in string manipulation instructions. ES
register can be changed directly using POP and LES instructions.
Figure 2.6 Memory Segments and Segment Register
Instruction Pointer
The instruction pointer contains a 16-bit offset which tells where in that 64-Kbyte
code segment the next instruction byte is to be fetched from. The actual physical
address sent to memory is produced by adding the offset contained in the IP
register to the segment base represented by the upper 16 bits in the CS register.
Segmnet:Offset Notation
Segment:Offset addressing was introduced at a time when the largest register in
a CPU was only 16-bits (or two bytes) which meant that it could address only
65,536 bytes (64kb) of memory directly. But everyone was hungry for a way to
run programs that were much larger than 64kb. Rather than creating a CPU with
9
larger register sizes (of at least 24-bits just to add another byte), the CPU
designers at Intel decided to stick with only 16-bit registers for their 8086 CPU
and change the way it would use them: They expanded the instruction set so it
could group two 16-bit registers together whenever the program needed to tell
the CPU to use an Absolute memory location that was too far off for a single two
byte register to contain the reference.
Unfortunately, they didn't simply combine two registers into a high and low order
(which would have given us a way to access up to 4 Gigabytes of memory.
Instead, they came up with the Segment:Offset scheme which allowed a CPU to
effectively address only about 1 Megabyte of memory. Keep in mind, however,
that this was at a time when no one could dream of a PC with more than 640kb
of memory
The scheme works like this: The value in any register considered being a
Segment register is multiplied by 16 (or shifted one hexadecimal byte to the left;
add an extra 0 to the end of the hex number) and then the value in an Offset
register is added to it. So, the Absolute address for any combination of Segment
and Offset pairs is found by using the formula
Physical Memeory Location = (Segment value * 16) + Offset Value
This will become a lot easier once you've seen a few examples. The Absolute or
Linear address for the Segment:Offset pair, F000:FFFD can be computed quite
easily in your mind by simply inserting a zero at the end of the Segment value (
which is the same as multiplying by 16 ) and then adding the Offset value:
F0000
+ FFFD
-----FFFFD or 1,048,573(decimal)
Here's another example: 923F:E2FF ->
923F0
+ E2FF
-----A06EF or 657,135(decimal)
Now let's compute the Absolute Memory location for the largest value that can be
expressed using a Segment:Offset reference
FFFF0
+ FFFF
------10FFEF or 1,114,095 (decimal)
10
In reality, it wasn't until quite some time after the 8086, that such a large value
actually corresponded to a real Memory location. Once it became common for
PCs to have over 1MB of memory, programmers developed ways to use it to
their advantage and this last byte became part of what's now called the HMA
(High Memory Area). But until that time, if a program tried to use a
Segment:Offset pair that exceeded a 20-bit Absolute address (1MB), the CPU
would truncate the higher bits, effectively mapping any value over FFFFFh
(1,048,575) to an address within the first Segment. Thus, 10FFEFh was mapped
to FFFEh.
One of the downsides in using Segment:Offset pairs (and likely what confuses
most of you) is the fact that a large number of these pairs refer to the same exact
memory locations. For example, every Segment:Offset pair below, refers to
exactly the same location in memory:
0007:7B90 0008:7B80 0009:7B70 000A:7B60 000B:7B50 000C:7B40
0047:7790 0048:7780 0049:7770 004A:7760 004B:7750 004C:7740
0077:7490 0078:7480 0079:7470 007A:7460 007B:7450 007C:7440
01FF:5C10 0200:5C00 0201:5BF0 0202:5BE0 0203:5BD0 0204:5BC0
07BB:0050 07BC:0040 07BD:0030 07BE:0020 07BF:0010 07C0:0000
All the above Segment:Offset pairs are only some of the many ways to refer to
the single absolute memory location of 7C00h.
As a matter of fact there may be up to 4096 different Segment:Offset pairs for
addressing a single byte in Memory; depending upon its particular location. For
absolute addresses 0h through FFEFh (o through 65,519), the number of
different pairs can be computed as follows:


Divide the absolute address by 16 (which shifts all the hex digits one place
to the right)
Throw away any fractional remainder and add 1
This is the same thing as saying: Add 1 to the segment number if the offset is
000Fh (15) or less. For example, the byte in memory referenced by the
Segment:Offset pair 0040:0000 has a total of 41h (or 65) different pairs that
might be used. For the Absolute address 7C00h, which was mentioned above,
there's a total of: 7C00 / 10h --> 7C0 + 1 = 7C1 (or 1,985) relative ways to
address this same memory location using Segment:Offset pairs. For the absolute
addresses from FFF0h (65,520) all the way through FFFFFh (1,048,575), there
will always be 4,096 Segment:Offset pairs one could use to refer to these
11
addresses. That's a little over 88% of the memory that can be accessed using
Segment:Offsets. The last 65,520 bytes that can be accessed by this method are
collectively called the High Memory Area (HMA). For each 16 bytes higher in the
HMA that we point to, there is one less Segment:Offset pair available to
reference that paragraph.
Since BIU takes care of the interaction with memory and other peripherals EU is
able to concentrate in the processing of data. Moreover the maintenance of the
instruction queue enables the 8086 microprocessor unit (MPU) to achieve
pipelining. Overall, the performance of 8086 is improved considerably.
Have you understood?
1. What are the two functional units of 8086 processor?
2. What is the function of the BIU?
3. What is the function of the EU?
4. What is the purpose of the Instruction Queue of BIU?
5. How does the physical memory location is computed in segment:offset
notation?
6. What is the function of the base pointer?
7. What are the functions of SI and DI registers?
8. State the purpose of the four segment registers.
2.4 Properties and Pin Description
Intel 8086 is a 16-bit HMOS microprocessor. It is a 40 pin IC. It uses a 5V d.c.
supply for its operation. The 8086 uses 20-line address bus. It can directly
address up to 1MB (220=1MB) of memory address. It uses 16-line data bus. 16bit data word is sub divided into a low-order byte and a high-order byte. The 20
lines of the address bus operate in multiplexed mode. The 16-low order address
bus lines are multiplexed with data and 4 high-order address bus lines are
multiplexed with status signals. The schematic diagram of Intel 8086 is shown in
figure 2.7.
AD0-AD15 (Bidirectional) – Address/Data bus. These are low order address bus.
They are multiplexed with data. When AD lines are used to transmit memory
address the symbol A is used instead of AD, for example A0-A15. When data are
transmitted over AD lines the symbol D is used in place of AD, for example D0D7, D8-D15 or D0-D15.
A16-A19 (Output) – High order address bus. These are multiplexed with status
signals.
A16/S3, A17/S4, A18/S5, A19/S6 – The specified address lines are multiplexed
with corresponding status signals.
12
BHE (Active Low)/S7 (Output) – Bus High Enable/Status. During T1 it is low. It is
used to enable data onto the most significant half of data bus, D8-D15. 8-bit
device connected to upper half of the data bus use BHE (Active Low) signal. It is
multiplexed with status signal S7. S7 signal is available during T2, T3 and T4.
RD (Read) (Active Low) – The signal is used for read operation. It is an output
signal. It is active when low.
READY (Input) – The addressed I/O or memory sends acknowledgement
through this pin. When HIGH it indicates that the peripheral is ready to transfer
data.
RESET (Input) – System reset. The signal is active high.
CLK (Input) – Clock. 5, 8 or 10 MHz.
INTR – Interrupt Request
NMI (Input) – Non-maskable Interrupt Request
TEST (Active Low) (Input) – Wait for test control. When it is low the
microprocessor continues execution otherwise waits.
Vcc – Power Supply ( +5V D.C.)
GND – Ground
13
Figure 2.7 Pin diagram of 8086
2.5 Addressing Modes
The way of specifying the address of an operand by a processor is called
addressing mode. 8086 microprocessor supports following addressing modes.
Implied Addressing – The data value/data address is implicitly associated with
the instruction. Hence no need to specify the operand explicitly in this addressing
mode.
Register Addressing – The data is specified by referring the register or the
register pair in which the data is present. This is also called register direct
addressing.
Immediate Addressing – The data itself is provided in the instruction. Hence in
this addressing mode it is not necessary for the microprocessor to refer a
memory location or a register/register pair.
Direct Addressing – The instruction operand specifies the memory address
where data is located. Hence a memory reference is required to locate the
operand. In all the addressing modes where one or more memory references are
required it is necessary for the microprocessor to produce a 20-bit physical
14
address. It does this by adding a 16-bit value called effective address to a
segment base address represented by the 16-bit number in one of the four
segment registers. In direct addressing mode, we specify the effective address of
the operand.
Register indirect addressing – The instruction specifies a register containing an
address, where data is located. This addressing mode works with SI, DI, BX and
BP registers. The effective address is present in a register and that register is
specified in the instruction.
Based - 8-bit or 16-bit instruction operand is added to the contents of a base
register (BX or BP), the resulting value is a pointer to location where data
resides.
Indexed - 8-bit or 16-bit instruction operand is added to the contents of an index
register (SI or DI), the resulting value is a pointer to location where data resides.
15
Based Indexed - the contents of a base register (BX or BP) is added to the
contents of an index register (SI or DI), the resulting value is a pointer to location
where data resides.
Based Indexed with displacement - 8-bit or 16-bit instruction operand is added to
the contents of a base register (BX or BP) and index register (SI or DI), the
resulting value is a pointer to location where data resides.
For example, if
(BX) = 0158
(DI) = 10A5 Displacement = 1B57
(DS) = 2100
and DS is used as the segment register, then the effective and physical
addresses produced by these quantities and the various addressing modes
would be
Direct: EA = 1B57
Physical address = 1B57+21000 = 22B57
Register: No effective address – datum is in specified register.
EA = 0158
Physical address = 0158 + 21000 = 21158
16
Register relative assuming register BX
EA = 0158 + 1B57 = 1CAF
Physical Address = 1CAF + 21000 = 22CAF
Based indexed assuming registers BX and DI
EA = 0158 + 10A5 + 11FD
Physical Address = 11FD + 21000 = 221FD
Relative based indexed assuming BX and DI
EA = 0158 + 10A5 + 1B57 = 2D54
Physical Address = 2D54 + 21000 = 23D54
Have you understood?
1. What is meant by addressing mode?
2. How is the effective address computed in based indexed addressing mode?
3. In which addressing mode the 16-bit effective address of the datum is a part of
the
instruction?
4. Differentiate between direct addressing mode and the implied addressing
mode.
2.6 Instruction Set
The 8086 instructions treat different types of operands uniformly. Nearly every
instruction can operate on either byte or word data. Register, memory and
immediate operands can be specified interchangeably in most instructions.
Immediate values are exceptions: they must serve as source operands and not
destination operands. Memory variables can be manipulated (added to,
subtracted from, shifted, compared) without being moved into and out of
registers.
This saves instructions, registers and execution time in assembly language
programs. In
high-level languages, where most variables are memory-based, compilers can
produce faster and shorter object programs. The 8086 Modular Core family
instruction set can be viewed as existing on two levels. One is the assembly level
and the other is the machine level. To the assembly language programmer, the
8086 Modular Core family appears to have about 100 instructions. One MOV
(data move) instruction, for example, transfers a byte or a word from a register, a
memory location or an immediate value to either a register or a memory location.
The 8086 Modular Core family CPUs, however, recognize 28 different machine
versions of the MOV instruction. The two levels of instruction sets address two
requirements: efficiency and simplicity. Approximately 300 forms of machinelevel instructions make very efficient use of storage. For example, the machine
17
instruction that increments a memory operand is three or four bytes long because
the address of the operand must be encoded in the instruction. Incrementing a
register, however, requires less information, so the instruction can be shorter.
The 8086 Core family has eight single-byte machine-level instructions that
increment different 16-bit registers.
The assembly level instructions simplify the programmer’s view of the instruction
set. The programmer writes one form of an INC (increment) instruction and the
assembler examines the operand to determine which machine level instruction to
generate. The following paragraphs provide a functional description of the
assembly-level instructions.
2.6.1 Data Transfer Instructions
The instruction set contains 14 data transfer instructions. These instructions
move single bytes and words between memory and registers. They also move
single bytes and words between the AL or AX register and I/O ports. Table 2-3
lists the four types of data transfer instructions and their functions.
Data transfer instructions are categorized as general purpose, input/output,
address object and flag transfer. The stack manipulation instructions, used for
transferring flag contents and instructions used for loading segment registers are
also included in this group. Figure 2-11 shows the flag storage formats. The
address object instructions manipulate the addresses of variables instead of the
values of the variables.
Data transfer instructions are categorized as general purpose, input/output,
address object and flag transfer. The stack manipulation instructions, used for
transferring flag contents and instructions used for loading segment registers are
also included in this group. The address object instructions manipulate the
addresses of variables instead of the values of the variables.
18
Examples
MOV DS, AX
MOV [BX], DX
Move (AX) to DS
Move (DX) into location indicated by (BX)
2.6.2 Arithmetic Instructions
Table 2.1 shows the various arithmetic instructions operate on four types of
numbers:




Unsigned binary
Signed binary (integers)
Unsigned packed decimal
Unsigned unpacked decimal
Table 2.2 shows the interpretations of various bit patterns according to number
type. Binary numbers can be 8 or 16 bits long. Decimal numbers are stored in
bytes, two digits per byte for packed decimal and one digit per byte for unpacked
decimal. The processor assumes that the operands in arithmetic instructions
contain data that represents valid numbers for that instruction. Invalid data may
produce unpredictable results. The Execution Unit analyzes the results of
arithmetic instructions and adjusts status flags accordingly.
19
Table 2.1 Arithmetic Operations
Table 2.2 various bit patterns according to Number Type
20
Examples
Suppose that (AL) = B4, which is -76 (in decimal) as an 8-bit signed integer and
180 (in decimal) as an unsigned integer, and the (BL) = 11, which is 17 (in
decimal) both as an 8-bit signed integer and as an unsigned integer. Then
IMUL BL
would cause (AX) = FAF4 = -1292 (in decimal) and (CF) = (OF) = 1 (which
implies that the result can not be put in 8 bits). The instruction
MUL BL
would cause the (AX) = 0BF4 = 3060 (in decimal) and (CF) = (OF) = 1 (which
again indicates that the product is too large for 8 bits).
CMP CX,BX subtracts the contents of register BX from the contents of CX and
decides whether CX=BX or CX>BX or CX<BX base don the contents of CF, ZF
or SF as follows.
CX=BX
CX>BX
CX<BX
CF
0
0
1
ZF
1
0
0
SF
0
0
1
2.6.3 Logical Instructions
Various logical instructions supported by 8086 are shown in Table 2.3. Logical
instructions include the Boolean operators NOT, AND, OR and exclusive OR
(XOR), as well as a TEST instruction. The TEST instruction sets the flags as a
result of a Boolean AND operation but does not alter either of its operands.
Individual bits in bytes and words can be shifted either arithmetically or logically.
Up to 32 shifts can be performed, according to the value of the count operand
coded in the instruction. The count can be specified as an immediate value or as
a variable in the CL register. This allows the shift count to be a supplied at
execution time. Arithmetic shifts can be used to multiply and divide binary
numbers by powers of two. Logical shifts can be used to isolate bits in bytes or
words. Individual bits in bytes and words can also be rotated. The processor
does not discard the bits rotated out of an operand. The bits circle back to the
other end of the operand. The number of bits to be rotated is taken from the
count operand, which can specify either an immediate value or the CL register.
The carry flag can act as an extension of the operand in two of the rotate
instructions. This allows a bit to be isolated in the Carry Flag (CF) and then
tested by a JC (jump if carry) or JNC (jump if not carry) instruction.
Examples
Suppose if (DL) = 10001010 and NOT DL is executed then New (DL) =
01110101
21
Suppose if (AL) = 10010110 and (LOG_DATA) = 010111010 then the instruction
OR AL, LOG_DATA will produce New (AL) = 11011110
Table 2.3 Logical Instructions
2.6.4 String Instructions
Five basic string operations process strings of bytes or words, one element (byte
or word) at a time. Strings of up to 64 Kbytes can be manipulated with these
instructions. Instructions are available to move, compare or scan for a value, as
well as to move string elements to and from the accumulator. Table 2.4 lists the
string instructions. These basic operations can be preceded by a one-byte prefix
that causes the instruction to be repeated by the hardware, allowing long strings
to be processed much faster than is possible with a software loop. The
repetitions can be terminated by a variety of conditions. Repeated operations can
be interrupted and resumed.
22
Table 2.4 String Instructions
A string instruction can have a source operand, a destination operand, or both.
The hardware assumes that a source string resides in the current data segment.
A segment prefix can override this assumption. A destination string must be in
the current extra segment. The assembler does not use the operand names to
address strings. Instead, the contents of the Source Index (SI) register are used
as an offset to address the current element of the source string. The contents of
the Destination Index (DI) register are taken as the offset of the current
destination string element. These registers must be initialized to point to the
source and destination strings before executing the string instructions. The LDS,
LES and LEA instructions are useful in performing this function. String
instructions automatically update the SI register, the DI register, or both, before
processing the next string element. The Direction Flag (DF) determines whether
the index registers are autoincremented (DF = 0) or auto-decremented (DF = 1).
The processor adjusts the DI, SI, or both registers by one for byte strings or by
two for word strings.
If a repeat prefix is used, the count register (CX) is decremented by one after
each repetition of the string instruction. The CX register must be initialized to the
number of repetitions before the string instruction is executed. If the CX register
is 0, the string instruction is not executed and control goes to the following
instruction.
Examples
23
CMPSB instruction will compare the byte pointed to by SI with the byte pointed to
by DI and set the flags according to the result. It will also increment the pointers
SI and DI to point to the next string elements. The REPE prefix in front of this
instruction tells the 8086 to decrement the CX register after each compare and
repeat the CMPSB instruction if the compared bytes were equal and CX is not
yet decremented down to zero.
2.6.5 Program Transfer Instructions
The contents of the Code Segment (CS) and Instruction Pointer (IP) registers
determine the instruction execution sequence in the 8086 Modular Core family.
The CS register contains the base address of the current code segment. The
Instruction Pointer register points to the memory location of the next instruction to
be fetched. In most operating conditions, the next instruction will already have
been fetched and will be waiting in the CPU instruction queue. Program transfer
instructions operate on the IP and CS registers. Changing the contents of these
registers causes normal sequential operation to be altered. When a program
transfer occurs, the queue no longer contains the correct instruction. The Bus
Interface Unit obtains the next instruction from memory using the new IP and CS
values. It then passes the instruction directly to the Execution Unit and begins
refilling the queue from the new location.
The 8086 Modular Core family offers four groups of program transfer instructions
(shown in table 2.5). These are unconditional transfers, conditional transfers,
iteration control instructions and interrupt-related instructions. Unconditional
transfer instructions can transfer control either to a target instruction within the
current code segment (intrasegment transfer) or to a different code segment
(intersegment transfer). The assembler terms an intrasegment transfer SHORT
or NEAR and an intersegment transfer FAR. The transfer is made unconditionally
when the instruction is executed. CALL, RET and JMP are all unconditional
transfers. CALL is used to transfer the program to a procedure. A CALL can be
NEAR or FAR. A NEAR CALL stacks only the Instruction Pointer, while a FAR
CALL stacks both the Instruction Pointer and the Code Segment register. The
RET instruction uses the information pushed onto the stack to determine where
to return when the procedure finishes. Note that the RET and CALL instructions
must be the same type. This can be a problem when the CALL and RET
instructions are in separately assembled programs. The JMP instruction does not
push any information onto the stack. A JMP instruction can be NEAR or FAR.
Conditional transfer instructions are jumps that may or may not transfer control,
depending on the state of the CPU flags when the instruction is executed. Each
conditional transfer instruction tests a different combination of flags for a
condition (see Table 2-10). If the condition is logically TRUE, control is
transferred to the target specified in the instruction. If the condition is FALSE,
control passes to the instruction following the conditional jump. All conditional
jumps are SHORT. The target must be in the current code segment within –128
24
to +127 bytes of the next instruction’s first byte. For example, JMP 00H causes a
jump to the first byte of the next instruction.
Jumps are made by adding the relative displacement of the target to the
Instruction Pointer. All conditional jumps are self-relative and are appropriate for
position-independent routines. The interrupt instructions allow programs and
external hardware devices to activate interrupt service routines. The effect of a
software interrupt is similar to that of a hardware-initiated interrupt. The
processor cannot execute an interrupt acknowledge bus cycle if the interrupt
originates in software or with an NMI (Non-Maskable Interrupt).
Examples
CMP TOTAL, 100
JGE EXIT
would result in a branch to EXIT if the contents of TOTAL are greater than or
equal to 100.
JMP TABLE[SI] would get the branch address from the memory location whose
address is that of TABLE+(SI). This instruction would cause the branch address
to be selected from an array of addresses and could be used as part of a
multiple-branch decision.
Table 2.5 Program Transfer Instructions
25
26
2.6.6 Processor Control Instructions
Processor control instructions shown in Table 2.6 allow programs to control
various CPU functions. Seven of these instructions update flags, four of them are
used to synchronize the microprocessor with external events, and the remaining
instruction causes the CPU to do nothing. Except for flag operations, processor
control instructions do not affect the flags.
Table 2.6 Processor Control Instructions
Have you understood?
1. What is the difference between ADD and ADC instructions?
2. Mention the status of the related flags in deciding equal to, greater than
and less than relationships.
3. Differentiate between JBE and JNA instructions.
4. What is the purpose of the process control instructions?
2.7 Assembler Directives
Assembler directives give instruction to the assembler where as other
instructions discussed in the above section give instruction to the 8086
microprocessor. Assembler directives are specific for a particular assembler.
However all the popular assemblers like the Intel 8086 macro assembler, the
turbo assembler and the IBM macro assembler use common assembler
directives.
The ASSUME directive tell the assembler the name of the logical segment it
should use for a specified segment.
The DB directive is used to declare a byte-type variable or to set aside one or
more storage locations of type byte in memory (Define Byte).
27
The DD directive is used to declare a variable of type doubleword or to reserve
memory locations which can be accessed as type doubleword. (Define
Doubleword)
The DQ directive is used to tell the assembler to declare a variable 4 words in
length or to reverse 4 words of storage in memory. (Define Quadword)
The DT directive is used to tell the assembler to define a variable which is 01
bytes in length or to reserve 10 bytes of storage in memory. (Define Ten Bytes)
The DW directive is used to tell the assembler to define a variable of type word or
to reserve storage locations of type word in memory. (Define Word)
The END directive is put after the last statement of a program to tell the
assembler that this is the end of the program module.
The ENDP directive is used along with the name of the procedure to indicate the
end of a procedure to the assembler.
The ENDS directive is used with the name of a segment to indicate the end of
that logical segment.
The EQU is used to give a name to some value or symbol.
The EVEN directive tells the assembler to increment the location counter to the
next even address if it is not already at an even address. This directive is useful
since 8086 can read a series of words much more quickly if they are at even
addresses.
The EXTRN directive is used to tell the assembler that the names or labels
following the directive are in some other assembly module.
The GLOBAL directive can be used in place of a PUBLIC directive or in place of
an EXTERN directive. For a name or symbol defined in the current assembly
module, the GLOBAL directive is used to make the symbol available to other
modules.
The GROUP directive is used to tell the assembler to group the logical segments
named after the directive into one logical group segment. This allows the
contents of all the segments to be accessed from the same group segment base.
The INCLUDE directive is used to tell the assembler to insert a block of source
code from the named file into the current source module.
28
The LABEL directive is used to give a name to the current value in the location
counter. The LABEL directive must be followed by a term which specifies the
type you want associated with that name.
The LENGTH is an operator which tells the assembler to determine the number
of elements in some named data item, such as a string or an array.
The NAME directive is used to give a specific name to each assembly module
when programs consisting of several modules are written.
The OFFSET is an operator which tells the assembler to determine the offset or
displacement of a named data item (variable) or procedure from the start of the
segment which contains it.
The ORG directive is used to set the location counter to a desired value at any
point in the program.
The PROC directive is used to identify the start of a procedure. The PROC
directive follows a name you give the procedure. After the PROC directive, the
term near or far is used to specify the type of the procedure.
The PTR operator is used to assign a specific type to a variable or to a label. It is
necessary to do this in any instruction where the type of the operand is not clear.
In order for the various modules of a large program to link together correctly, any
variable name or label referred to in other modules must be declared public in the
module in which it is defined. The PUBLIC directive is used to tell the assembler
that a specified name or label will be accessed from other modules.
The SEGMENT directive is used to indicate the start of a logical statement.
Preceding the SEGMENT directive is the name you want to give the segment.
The SHORT operator is used to tell the assembler that only 1-byte displacement
is needed to code a jump instruction.
The TYPE operator tells the assembler to determine the type of a specified
variable. The assembler actually determines the number of bytes in the type of
the variable.
Have you understood?
1. What is the difference between the routine instructions and directives in an
assembly language program?
2. Differentiate between the assembler directive and the assembler operator.
3. Give examples for assembler operators.
29
2.8 Writing an Assembly Language Program
Writing assembly language programs for 8086 is slightly different from that of
writing assembly language programs for 8085. In addition to the instructions that
are meant for solving the problem, some additional instructions are required to
complete the programs. The purpose of these additional programs is to initialize
various parts of the system, such as segment registers, flags and programmable
port devices. Some of the instructions are to handle the stack of the 8086 based
system. If we use stack in our program, then it is necessary to load the stack
segment register and an instruction to load the stack pointer register with the
offset of the top of the stack. Another purpose of these additional instructions is
to handle the programmable peripheral devices such as ports, timers and
controllers. The programmable peripheral interfaces should be assigned suitable
control words to make them to function in the way as we expect. The best way to
approach the initialization task is to make a checklist of all the registers,
programmable devices and flags in the system we are working on. Then we can
mark the ones we need for a specific program and determine the instructions
needed to initialize each part.
An 8086 assembly language program has five columns namely address, data or
code, labels, mnemonics, operands and comments. The address column is used
for the address or the offset of a code byte or a data byte. The actual code bytes
or data bytes are put in the data or code column. A label is a name which
represents an address referred to in a jump or call instruction. Labels are put in
the labels column. A label is followed by a colon (:) if it is used by a jump or call
instruction in the same code segment. The mnemonics column contains the
opcode mnemonics for the instructions. The operands column contains the
registers, memory locations or data acted upon by the instructions. A comments
column gives space to describe the function of the instruction for future
reference.
An assembly language program to multiply two 16-bit numbers
DATA
SEGMENT
MLND_NUMBER
MLPR_NUMBER
RESULT
DW 2036H
DW 3178H
DW 2 DUP (0)
DATA
CODE
START:
SEGMENT
ASSUME
CS:CODE, DS:DATA
MOV AX, DATA
MOV DS, AX
MOV AX, MLND_NUMBER
MUL MLPR_NUMBER
30
CODE
MOV RESULT, AX
MOV RESULT+2, DX
INT 3
ENDS
END START
Various functions performed by the above program are
 Initialize the segment registers
 Move the multiplicand in the accumulator
 Multiply the contents of the accumulator with the multiplier
 Store the result in adjacent memory locations
An assembly language program that compares two strings is shown as follows.
DATA
DATA
CODE
CODE
SEGMENT
STRINGONE
STR_LENGTH
STRINGTWO
ENDS
DB
‘ANNAUNIV’
EQU ($ - STRINGONE)
DB
8 DUP(0)
SEGMENT
ASSUME
CS:CODE, DS:DATA, ES:DATA
MOVE AX, DATA
MOVE DS, AX
MOVE ES, AX
MOV DX, 0FFFEH
MOV AL, 99H
OUT DX, AL
LEA SI, STRINGONE
LEA DI, STRINGTWO
MOV CX, STR_LENGTH
CLD
REPE
CMPSB
JNE NO_MATCH
JMP MATCH
NO_MATCH: MOV AL, 01
MOV DX, 0FFFAH
OUT DX, AL
HLT
MATCH:
NOP
ENDS
END
Various functions performed by the above program are
 Initialize the segment registers
 Setup an output port
31







Load source pointer
Load destination pointer
Load counter with string one length
Increment source index and destination index registers
Compare the two string bytes
If equal continue to compare the following bytes
If not equal, inform it by making an alarm
Summary
1. The Intel 8086 is a 16-bit microprocessor. 16-bit indicates that the word
length of the microprocessor. The 8086 microprocessor is able to process
16 bits of information at a time.
2. The 8086 CPU logic has been partitioned into two functional units namely
Bus Interface Unit (BIU) and Execution Unit (EU).
3. The BIU has to interact with memory and input and output devices in
fetching the instructions and data required by the EU and in sending the
results produced by EU to the memory or the output device.
4. The EU is responsible for executing the instructions of the programs and
to carry out the required processing.
5. The Execution Unit (EU) of 8086 microprocessor has control unit,
instruction decoder, Arithmetic and Logical Unit (ALU), general registers,
flag register, pointers and index registers.
6. The BIU has an instruction stream byte queue, a set of segment registers
and instruction pointer.
7. In the Segment:Offset scheme the value in any register considered being
a Segment register is multiplied by 16 (or shifted one hexadecimal byte to
the left; add an extra 0 to the end of the hex number) and then the value in
an Offset register is added to it.
8. The way of specifying the address of an operand by a processor is called
addressing mode.
9. The various types of addressing modes supported by 8086 are implied,
register, immediate, direct and register indirect modes.
10. The 8086 instruction set includes data transfer instructions, arithmetic
instructions, logical instructions, string instructions, program transfer
instructions and process control instructions.
11. Assembler directives give instruction to the assembler where as other
instructions give instruction to the 8086 microprocessor.
12. An 8086 assembly language program includes some additional
instructions besides the instructions that are meant for solving the
problem. The purpose of these additional instructions is to initialize various
parts of the system, such as segment registers, flags and programmable
port devices.
32
In this unit, you have learnt about the architecture, addressing modes and
instruction set of 8086 a 16-bit microprocessor. Even though 8086 was designed
and implemented with the intention of using it in a general purpose digital
computer, it was never used due to the incompatibility problem that existed with
the peripherals of that time. Personal computers were designed and
implemented using 8088 an 8-bit processor externally and 16-bit processor. Unit
III deals with interfacing the peripherals to the microprocessor and designing a
microcomputer in terms of 8086 microprocessor.
Exercises
1. Describe the function of the 8086 queue. How does the queue speed up
processing?
2. What physical address is represented by 4370:561EH and 7A32:0028H?
3. Describe the difference between the instructions MOV AX,2437H and
MOV AX, [2437H].
4. Write an 8086 assembly language program to convert a 16-digit unpacked
BCD number to a packed BCD number.
5. Explain the EVEN directive with an example.
Answers
1. To execute an instruction it is necessary for the 8086 microprocessor to
decode the instruction into opcode and operands. Usually the Execution
Unit performs this job. The EU does not require the use of buses for this
job. Hence the Bus Interface Unit (BIU) stores these prefetched bytes in a
first in first out register set called a queue. When the EU is ready for its
next instruction, it simply reads the instruction byte(s) for the instruction
from the queue in the BIU. This is much faster than sending out an
address to the system memory and waiting for memory to send back the
next instruction byte or bytes.
2. 4370:561EH
43700
+561E
--------48D1E
--------7A32:0028H
7A320
+0028
--------7A348
3. MOV AX, 2437H moves the 16 bit number 2437H into accumulator.
33
MOV AX, [2437H] moves the 16 bit number present in the memory
location whose address is represented by the offset 2437H
4.
MOV DX,8
MOV CL,4
MOV SI,0
MOV DI,SI
CONV: MOV AX,WORD PTR UNPACKED[SI]
SHL AL,CL
SHR AX,CL
MOV PACKED[DI], AL
ADD SI,2
INC DI
DEC DX
JNZ CONV
5. DATA_HERE SEGMENT
;Location counter will point
;to 0009 after assembler
;reads next statement
SLAVES_AVERAGES DB 9 DUP(?)
;declare array of 9 bytes
EVEN ;increment location
;counter to 000AH
INVENTORY_RECORDS DW 100 DUP(0)
; Array of 100 words starting
; on even address for
; quicker read
DATA_HERE ENDS
34