[go: up one dir, main page]

0% found this document useful (0 votes)
27 views87 pages

Advance Microprocessor Handout

Download as pdf or txt
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 87

Chapter 1 The 8086/8088 MICROPROCESSORS

CHAPTER

THE 8086/8088 MICROPROCESSORS


Introduction
8086 Internal Architecture
The Execution Unit
Flag Register
The General Purpose Registers
The Bus Interface Unit
The Instruction Queue
The Segment Registers
The Instruction Pointer
The Stack Segment Register
Pointer And Index Registers In The Execution Unit
Signal Description of 8086
Physical Memory Organization
I/O Addressing Capability
The Processor 8088
Comparing 8086 and 8088
Minimum and Maximum Modes
The Need for Segmentation

1.1 Introduction
With the advent of the first 4-bit microprocessor 4004 from Intel
Corporation in 1971, there has been a silent revolution in the domain of digital
system design, which has shaken many facets of the current technological
progress. In the last 28 years the world has seen an evolution of microprocessors,
whose impact on today's technological scenario is phenomenal.
This evolution was possible because of the tremendous advances in the
semiconductor process technology. The first microprocessor 4004 contained only
ten thousand transistors while the component density increased more than
threefold in less than a decade's time. Immediately after the introduction of the
4004, Intel introduced the first eight bit microprocessor 8008 in 1972; these
processors were, however, not successful because of their inherent limitations. In
1974, Intel released the first general-purpose 8-bit microprocessor 8080. This CPU
also was not functionally complete and the first 8-bit functionally complete CPU
8085 was introduced in 1977.

2
Chapter 1 The 8086/8088 MICROPROCESSORS

The major limitations of these 8-bit microprocessors are their limited


memory addressing capacity, slow speed of execution, limited number of
scratchpad registers and non-availability of complex instruction set and
addressing modes. Another important point is that 8085 does not support
adequate pipelining or parallelism, which is so important for enhancing the
speed of computation. For example, the non-availability of any instruction queue
in an 8085 CPU leads to a situation where the fetching of opcode and operands
along with the execution takes place in an absolutely sequential manner. The first
16-bit CPU from Intel was a result of the designers' efforts to produce a more
powerful and efficient computing machine. The designers of 8086 CPU had taken
note of the major limitations of the previous generations of the 8-bit CPUs. The
8086 contain a set of 16-bit general-purpose registers, support a 16-bit ALU, a
rich instruction set and provide segmented memory addressing scheme. The
introduction of a set of segment registers for addressing the segmented memory
in 8086 was indeed a major step in the process of evolution. All these features
made this 16-bit processor a more efficient CPU.
The development of IBM PC started in July 1980, and precisely after one
year, the first machine based on Intel 8088 CPU (which is functionally equivalent
to 8086 but supports only 8-bit external data bus) with 1 or 2 floppy disk drives, a
keyboard and a monochrome monitor was announced in August 1981. With the
introduction of each new generation of microprocessors, the performance of the
Personal Computers has also been enriched. The major limitation in 8086 was
that it did not have the memory management and protection capabilities, which
were considered an extremely important feature, deemed to be an integral part of
a CPU of the eighties. 80286 was the first CPU to possess the ability of memory
management, privilege and protection. However, the 80286 CPU also had a
limitation on the maximum segment size supported by it (only 64 Kb). Another
limitation of 80286 was that, once it was switched into protected mode, it was

3
Chapter 1 The 8086/8088 MICROPROCESSORS

difficult to get it back to real mode. The only way of reverting it to the real mode
was to reset the system.
In the mid eighties the more computationally demanding problems
necessitated the development of still faster CPUs. Thus appeared 80386, which
was the first 32-bit CPU from Intel. The memory management capability of 80286
was enhanced to support virtual memory, paging and four levels of protection.
The design of 80386 circumvented this problem. Moreover, the maximum
segment size in 80386 was enhanced and this could be as large as 4 Gb with
80386 supporting as many as 16384 segments. The 80386 along with its math
coprocessor 80387, provided a high speed environment. 80486 was designed with
an integrated math coprocessor. After getting integrated, the speed of execution
of mathematical operations enhanced three folds. Also for the first time an 8 Kb
four-way set associative code and data cache was introduced in 80486. A five-
stage instruction pipelining was also introduced.
The earlier generation CPUs supported rather crude instruction sets. It
was not expected that the programmers those days would write large machine
code programs. A single high-level instruction might be compiled into ten or
even hundred machine code operations. In the course of evolution from the early
8-bit CPUs, the trend was to design CPUs, which could support more and more
complex instructions at the assembly language level. Designers of complex
instruction set computers (CISC) wanted to reduce this gap.
Since the early days of microprocessor development the designers have
tried to make them more powerful by designing more complex instructions. But
then some of these powerful instructions and addressing modes were hardly
used by the programmers. In fact some of these instructions' logic took up a large
part of the microprocessors' silicon chip. The reduced instruction set computer
(RISC) designers observed that the data movement type of machine instructions
are frequently executed by the CPU. They have optimized the CPUs to execute

4
Chapter 1 The 8086/8088 MICROPROCESSORS

these instructions rapidly. RISC provided a regular set of instructions having the
same format with a lot of pipelining.
To improve the processor's performance, the possible ways are suggested
below.
(a) Increasing the processor and system clock rate.
(b) Optimizing and improving the instruction set.
(c) Executing multiple instructions in one cycle and incorporating parallelism
in the CPU architecture.
The first option is applicable both to CISC and RISC processors. The
second option is primarily for CISC but is applicable to RISC as well. The third
option is more suited to RISC CPUs. Ever since the appearance of commercially
available RISC CPUS, there has been a debate over the performance of RISC
versus CISC. The RISC architects argue that their instructions may be executed in
a single cycle and thus take less time than is taken by a CISC CPU. This is
because of pipelining, reduction of instructions to a simple operation and
synthesis of complex operations with compiler generated code sequences. When
RISC machines first arrived in the market, CISC processors were performing at 6-
10 cycles per instruction, while the RISC CPUs could execute a set of simpler
instructions in one cycle and offer better performance. Many of the CISC
processors have subsequently used many features of RISC.
8086 microprocessor has a much more powerful instruction set along with
the architectural developments which imparted substantial programming
flexibility and improvement in speed over the 8-bit microprocessors.
The peripheral chips designed earlier for 8085 were compatible with
microprocessor 8086 with slight or no modifications. Though there is a
considerable difference between the memory addressing techniques of 8085 and
8086, the memory interfacing technique is Similar. But includes the use of a few
additional signals.

5
Chapter 1 The 8086/8088 MICROPROCESSORS

1.2 8086 Internal Architecture


As shown by the block diagram in the Figure, the 8086 CPU is divided
into two independent functional parts, the bus Interface unit or BIU, and the
execution unit or EU. Dividing the work between these two units speeds up
processing.

Fig: 8086 Internal Block Diagram


The bus interface unit contains the circuit for physical address calculations
and a pre-decoding instruction byte queue (6 bytes long). The bus interface unit
makes the system bus signals available for external interfacing of the devices. In
other words, this unit is responsible for establishing communications with
external devices and peripherals including memory via the bus. As already
stated, the 8086 addresses a segmented memory. The complete physical address,
which is 20-bits long, is generated using segment and offset registers, each 16-bits
long.

6
Chapter 1 The 8086/8088 MICROPROCESSORS

For generating a physical address from contents of these two registers, the
content of a segment register also called as segment address is shifted left bit-
wise four times and to this result, content of an offset register also called as offset
address is added, to produce a 20-bit physical address. For example, if the
segment address is 1005H and the offset is 5555H, then the physical address is
calculated as below.
Segment address --------- 1005H
Offset address------------- 5555H
Segment address------- -- 1005H --------- 0001 0000 0000 0101
Shifted by 4 bit positions---------------- 0001 0000 0000 0101 0000 +
Offset address------------------------------------ 0101 0101 0101 0101
Physical address ------------------------- 0001 0101 0101 1010 0101
1 5 5 A 5
Thus the segment addressed by the segment value 1005H can have offset
values from 0000H to FFFFH within it, i.e. maximum 64K locations may be
accommodated in the segment. Thus the segment register indicates the base
address of a particular segment, while the offset indicates the distance of the
required memory location in the segment from the base address. Since the offset
is a 16-bit number, each segment can have a maximum of 64K locations. The bus
interface unit has a separate adder to perform this procedure for obtain- ing a
physical address while addressing memory. The segment address value is to be
taken from an appropriate segment register depending upon whether code, data
or stack are to be accessed, while the offset may be the content of IP, BX, SI, DI,SP
or an immediate 16-bit value, depending upon the addressing mode.
1.2.1 THE EXECUTION UNIT
Control Circuitry, Instruction Decoder, And ALU
As shown in the Figure, the EU contains control circuitry, which directs
internal operations. A decoder in the EU translates instructions fetched from
memory into a series of actions, which the EU carries out. The EU has a 16-bit
arithmetic logic unit which can add, subtract, AND, OR, XOR, increment,
decrement, complement, or shift binary numbers.

7
Chapter 1 The 8086/8088 MICROPROCESSORS

1.2.1.1. Flag Register


A flag is a flip-flop, which indicates some condition produced by the
execution of an instruction, or controls certain operations of the EU. A 16-bit flag
register in the EU contains nine active flags. Following figure shows the location
of the nine flags in the flag register.

Six of the nine flags are used to indicate some condition produced by an
instruction. For example, a flip-flop called the carry flag will be set to a 1 if the
addition of two 16- bit binary numbers produces a carry out of the most
significant bit position. If no carry out of the MSB is produced by the addition,
then the carry flag will be a 0. The EU thus effectively runs up a "flag" to tell you
that a carry was produced.
The six conditional flags in this group are the carry flag (CF), the parity
flag (PF), the auxiliary carry flag (AF), the zero flag (ZF), the sign flag (SF), and
the overflow flag (OF). Certain 8086 instructions check these flags to determine
which of two alternative actions should be done in executing the instruction.
S-Sign Flag: This flag is set, when the result of any computation is negative. For
signed computations, the sign flag equals the MSB of the result.
Z-Zero Flag: This flag is set, if the result of the computation or comparison
performed by the previous instruction/instructions is zero.

8
Chapter 1 The 8086/8088 MICROPROCESSORS

P-Parity Flag: This flag is set to 1, if the lower byte of the result contains even
number of 1s.
C-Carry Flag: This flag is set, when there is a carry out of MSB in case of addition
or a borrow in case of subtraction.
T-Trap Flag: If this flag is set, the processor enters the single step execution
mode. In other words, a trap interrupt is generated after execution of each
instruction. The processor executes the current instruction and the control is
transferred to the Trap interrupt service routine.
I-interrupt Flag: If this flag is set, the maskable interrupts are recognized by the
CPU, otherwise, they are ignored.
D-Direction Flag: This is used by string manipulation instructions. If this flag bit
is '0’ the string is processed beginning from the lowest address to the highest
address, i.e. auto-incrementing mode. Otherwise, the string is processed from the
highest address towards the lowest address, i.e. auto-decrementing mode.
AC-Auxiliary Carry Flag: This is set, if there is a carry from the lowest nibble, i.e.
bit three, during addition or borrow for the lowest nibble, i.e. bit three, during
subtraction.
O-Overflow Flag: This flag is set, if an overflow occurs, i.e. if the result of a
signed operation is large enough to be accommodated in a destination register.
For example, in case of the addition of two signed numbers, if the result
overflows into the sign bit, i.e. the result is of more than 7-bits in size in case of 8-
bit signed operations and more than 15-bits in size in case of 16-bit signed
operations, and then the overflow flag will be set.
OF = C7 XOR C6 ( for 8-bit signed operations)
= C15 XOR C14 ( for 16-bit signed operations)
1.2.1.2. General-Purpose Registers
The EU has eight general-purpose registers, labeled AH, AL, BH, BL, CH,
DH, and DL. These registers can be used individually for temporary storage of 8-

9
Chapter 1 The 8086/8088 MICROPROCESSORS

bit data. Te AL register is also called the Accumulator. It has some features that
the other general-purpose registers do not have.
Certain pairs of these general-purpose registers can be used together to
store 16-bit data words. The acceptable register pairs are AH and AL, BH and BL,
CH and CL, and DH and DL. The AH-AL pair is referred to as the AX register,
the BH-BL pair is referred to as the BX register, the CH-CL pair is referred to as
the CX register, and the DH-DL pair is referred to as the DX register.
The 8086 general-purpose register set is very similar to those of the earlier-
generation 8080 and 8085 microprocessors. It was designed this way so that the
many programs written for the 8080 and 8085 could easily be translated to run on
the 8086 or the 8088. The advantage of using internal registers for the temporary
storage of data is that, since the data is already in the EU, it can be accessed much
more quickly than it could be accessed in external memory.
1.2.2 The Bus Interface Unit
1.2.2.1. THE INSTRUCTION QUEUE
While the EU is decoding an instruction or executing an instruction, which
does not require use of the buses, the BIU fetches up to six instruction bytes for
the following instructions. The 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. Except in the
cases of JMP and CALL instructions, where the queue must be dumped and then
reloaded starting from a new address, this prefetch-and-queue scheme greatly
speeds up processing. Fetching the next instruction while the current instruction
executes is called pipelining.
1.2.2.2. SEGMENT REGISTERS

10
Chapter 1 The 8086/8088 MICROPROCESSORS

The 8086 BIU sends out 20-bit addresses, so it can address any of 220 or
1,048,576 bytes in memory. However, at any given time the 8086 works with only
four 65,536-byte (64-Kbyte) segments within this 1,048,576- byte (1 -Mbyte)
range. Four segment registers in the BIU are used to hold the upper 16 bits of the
starting addresses of four memory segments that the 8086 is working with at a
particular time.
The four segment registers are the code segment (CS) register, the stack
segment (SS) register, the extra segment (ES) register, and the data segment (DS)
register. Figure given below shows how these four segments might be positioned
in memory at a given time. The four segments can be separated as shown, or, for
small programs, which do not need all 64 Kbytes in each segment they can
overlap.
A segment register is used to hold the upper 16 bits of the starting address
for each of the segments. The code segment register, for example, holds the
upper 16 bits of the starting address for the segment from which the BIU is
currently fetching instruction code bytes. The BIU always inserts zeros for the
lowest 4 bits (nibble) of the 20-bit starting address for a segment.

11
Chapter 1 The 8086/8088 MICROPROCESSORS

Fig: One way four 64-Kbyte segments might positioned within 1-Mbyte address space of
an 8086.
If the code segment register contains 348AH, for example, then the code
segment will start at address 348A0H. In other words, a 64-Kbyte segment can be
located anywhere within the 1-Mbyte address space, but the segment will always
start at an address with zeros in the lowest 4 bits. This constraint was put on the
location of segments so that it is only necessary to store and manipulate 16-bit
numbers when working with the starting address of a segment. The part of a
segment starting address stored in a segment register is often called the segment
base.
A stack is a section of 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. The extra segment register and
the data segment are used to hold the upper 16 bits of the starting addresses of
two memory segments that are used for data.

Fig: Addition of IP to CS to produce the Fig: Addition of SS and SP to produce the physical
physical address of the code byte. (a) address of the top of the stack
Diagram and (b) Computation.
12
Chapter 1 The 8086/8088 MICROPROCESSORS

1.2.2.3. INSTRUCTION POINTER


The next feature to look at in the BIU is the Instruction pointer (IP)
register. As discussed previously, the code segment registers holds the upper 16
bits of the starting address of the segment from which the BIU is currently
fetching instruction code bytes. The instruction pointer register holds the 16-bit
address, or offset, of the next code byte within this code segment. The value
contained in the IP is referred to as an offset because this value must be offset
from (added to) the segment base address in CS to produce the required 20-bit
physical address sent out by the BIU. Figure above shows in diagram form how
this works. The CS register points to the base or start of the current code
segment. The IP contains the distance or offset from this base address to the next
instruction byte to be fetched. Above figure shows how the 16-bit offset in IP is
added to the 16-bit segment base address in CS to produce the 20-bit physical
address. Notice that the two 16-bit numbers are not added directly in line,
because the CS register contains only the upper 16 bits of the base address for the
code segment. The BIU automatically inserts zeros for the lowest 4 bits of the
segment base address.
If the CS register, for example, contains 348AH, you know that the starting
address for the code segment is 348A0H. When the BIU adds the offset of 4214H
in the IP to this segment base address, the result is a 20-bit physical address of
38AB4H. An alternative way of representing a 20-bit physical address is the
segment base : offset form. For the address of a code byte, the format for this
alternative form will be CS:IP. As an example of this, the address 38AB4H, can
also be represented as 348A:4214.
To summarize, then, the CS register contains the upper 16 bits of the
starting address of the code segment in the 1 -Mbyte address range of the 8086.

13
Chapter 1 The 8086/8088 MICROPROCESSORS

The instruction pointer register 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.
Any time the 8086 accesses memory, the BIU produces the required 20-bit
physical address by adding an offset to a segment base value represented by the
contents of one of the segment registers.
STACK SEGMENT REGISTER AND STACK POINTER REGISTER
A stack, remember, is a section of memory set aside to store addresses and
data while a subprogram is executing. The 8086 allow you to set aside an entire
64-Kbyte segment as a stack. The upper 16 bits of the starting address for this
segment are kept in the stack segment register. The stack pointer (SP) register in
the execution unit holds the 16-bit offset from the start of the segment to the
memory location where a word was most recently stored on the stack. The
memory location where a word was most recently stored is called the top of
stack. Figure above, shows this in diagram form.

1.2.3. POINTER AND INDEX REGISTERS IN THE EXECUTION UNIT


In addition to the stack pointer register (SP), the EU contains a 16-bit base
pointer (BP) register. It also contains a 16-bit source index (SI) register and a 16-
bit destination Index (DI) register. These three registers can be used for
temporary storage of data just as the general-purpose registers described above.
However, their main use is to hold the 16-bit offset of a data word in one of the
segments. SI, for example, can be used to hold the offset of a data word in the
data segment.

14
Chapter 1 The 8086/8088 MICROPROCESSORS

Fig: Addition of data segment (DS) register


and effective address (BX) to produce the physical address of the data byte.

1.3 SIGNAL DESCRIPTIONS OF 8086


The microprocessor 8086 is a 16-bit CPU available in three clock rates, i.e.
5, 8 and 10 MHz, packaged in a 40 pin CERDIP or plastic package. The 8086
operates in single processor or multiprocessor configurations to achieve high
performance. The pin configuration is shown in the following figure. Some of the
pins serve a particular function in minimum mode (single processor mode) and
others function in maximum mode (multiprocessor mode) configuration.
The 8086 signals can be categorized in three groups. The first are the signals
having common functions in minimum as well as maximum mode, the second
are the signals, which have special functions for minimum mode, and the third
are the signals having special functions for maximum mode.
The following signal descriptions are common for both the minimum and
maximum modes.
AD 15 -AD 0 These are the time multiplexed memory I/0 address and data lines.
Address remains on the lines during T, state, while the data is available on the
data bus during T 2 ,T 3 ,T w , and T 4 Here T 1 ,T 2 ,T 3 ,T 4 and T w , are the clock states of
a machine cycle. T w is a wait state. These lines are active high and float to a
tristate during interrupt acknowledge and local bus hold acknowledge cycles.

15
Chapter 1 The 8086/8088 MICROPROCESSORS

Fig: The Pin Configuration of 8086


A 19 /S 6 ,A 18 /S 5 ,A 17 /S 4 , A 16 /S 3 These are the time multiplexed address and status
lines. During T 1 , these are the most significant address lines for memory
operations. During I/0 operations, these lines are low. During memory or I/0
operations, status information is available on those lines for T 2 , T 3 , T w , and T 4 .
The status of the interrupt enable flag bit (displayed on S 5 ) is updated at the
beginning of each clock cycle.
S4 S3 Indications
0 0 Alternate Data
0 1 Stack
1 0 Code or None

1 1 Data

Table: Bus High Enable/Status


The S 4 and S 3 combinedly indicate which segment register is presently being
used for memory accesses as shown in Table above. These lines float to tri-state
off (tristated) during the local bus hold acknowledge. The status line S 6 is always
low (logical). The address bits are separated from the status bits using latches
controlled by the ALE signal.
BHE/S 7 -Bus High Enable/Status The bus high enable signal is used to indicate
the transfer of data over the higher order (D 15 -D 8 ) data bus as shown in Table
below. It goes low for the data transfers over D 15 -D 8 and is used to derive chip
selects of odd address memory bank or peripherals. BHE is low during T 1 for
read, write and interrupt acknowledge cycles, whenever a byte is to be
transferred on the higher byte of the data bus. The status information is available

16
Chapter 1 The 8086/8088 MICROPROCESSORS

during T 2 , T 3 and T 4 . The signal is active low and is tristated during 'hold'. It is
low during T 1 for the first pulse of the interrupt acknowledge cycle.
BHE A0 Indications
0 0 Whole word
0 1 Upper byte from or to odd address
1 0 Lower byte from or to even address

1 1 None

RD-Read Read signal, when low, indicates the peripherals that the processor is
performing a memory or I/0 read operation. RD is active low and shows the
state for T 2 , T 3 , T w of any read cycle. The signal remains tristated during the
'hold acknowledge'.
READY This is the acknowledgement from the slow devices or memory that
they have completed the data transfer. The signal made available by the devices
is synchronized by the 8284A clock generator to provide ready input to the 8086.
The signal is active high.
INTR-interrupt Request This is a level triggered input. This is sampled during
the last clock cycle of each instruction to determine the availability of the request.
If any interrupt request is pending, the processor enters the interrupt
acknowledge cycle. This can be internally masked by resetting the interrupt
enable flag. This signal is active high and internally synchronized.
TEST This input is examined by a 'WAIT' instruction. If the TEST input goes low,
execution will continue, else, the processor remains in an idle state. The input is
synchronized internally during each clock cycle on leading edge of clock.
NMI Non-maskable Interrupt This is an edge-triggered input which causes a
Type2 interrupt. The NMI is not maskable internally by software. A transition
from low to high initiates the interrupt response at the end of the current
instruction. This input is internally synchronized.
RESET This input causes the processor to terminate the current activity and start
execution from FFFF0H. The signal is active high and must be active for at least

17
Chapter 1 The 8086/8088 MICROPROCESSORS

four clock cycles. It restarts execution when the RESET returns low. RESET is
also internally synchronized.
CLK Clock Input The clock input provides the basic timing for processor
operation and bus control activity. Its an asymmetric square wave with 33% duty
cycle. The range of frequency for different 8086 versions is from 5MHz to
10MHZ.
Vcc +5V power supply for the operation of the internal circuit. GND ground for
the internal circuit.
MN/MX The logic level at this pin decides whether the processor is to operate in
either minimum (single processor) or maximum (multiprocessor) mode. The
following pin functions are for the minimum mode operation of 8086.
M/ I/O -Memory/IO This is a status line logically equivalent to 92 in maximum
mode. When it is low, it indicates the CPU is having an 1/0 operation, and when
it is high, it indicates that the CPU is having a memory operation. This line
becomes active in the previous T4 and remains active till final T4 of the current
cycle. It is tristated during local bus "hold acknowledge".
INTA - Interrupt Acknowledge This signal is used as a read strobe for interrupt
acknowledge cycles. In other words, when it goes low, it means that the
processor has accepted the interrupt. It is active low during T2, T3 and Tw of
each interrupt acknowledge cycle.
ALE-Address Latch Enable This output signal indicates the availability of the
valid address on the address/data lines, and is connected to latch enable input of
latches. This signal is active high and is never tristated.
DT/R Data Transmit/Receive
This output is used to decide the direction of data flow through the
transreceivers (bi-directional buffers). When the processor sends out data, this
signal is high and when the processor is receiving data, this signal is low.

18
Chapter 1 The 8086/8088 MICROPROCESSORS

Logically, this is equivalent to S, in maximum mode. Its timing is the same as


M/I/O. This is tristated during 'hold acknowledge'.
DEN-Data Enable This signal indicates the availability of valid data over the
address/data lines. It is used to enable the transreceivers (bi-directional buffers)
to separate the data from the multiplexed address/data signal. It is active from
the middle of T2 until the middle of T4 DEN is tristated during ‘hold
acknowledge' cycle.
HOLD, HLDA - Hold/Hold Acknowledge When the HOLD line goes high, it
indicates to the processor that another master is requesting the bus access. The
processor, after receiving the HOLD request, issues the hold acknowledge signal
on HLDA pin, in the middle of the next clock cycle after completing the current
bus (instruction) cycle. At the same time, the processor floats the local bus and
control lines. When the processor detects the HOLD line low, it lowers the HLDA
signal. HOLD is an asynchronous input, and it should be externally
synchronized. If the DMA request is made while the CPU is performing a
memory or I/O cycle, it will release the local bus during T4 provided:
1. The request occurs on or before T2 state of the current cycle.
2. The current cycle is not operating over the lower byte of a word (or
operating on an odd address).
3. The current cycle is not the first acknowledge of an interrupt acknowledge
sequence.
4. A Lock instruction is not being executed.
So far we have seen the pin descriptions of 8086 in minimum mode.
The following pin functions are applicable for maximum mode operation of
8086.
S 2 , S 1 , S 0 - Status Lines These are the status lines which reflect the type of
operation, being carried out by the processor. These status lines are encoded in
the Table.
S2 S1 S0 Indications

19
Chapter 1 The 8086/8088 MICROPROCESSORS

0 0 0 Interrupt Acknowledge
0 0 1 Read I/O Port
0 1 0 Write I/O Port
0 1 1 Halt
1 0 0 Code Access
1 0 1 Read Memory
1 1 0 Write Memory
1 1 1 Passive

LOCK This output pin indicates that other system bus masters will be prevented
from gaining the system bus, while the LOCK signal is low. The LOCK signal is
activated by the 'LOCK’ prefix instruction and remains active until the
completion of the next instruction. This floats to tri-state off during 'hold
acknowledge". When the CPU is executing a critical instruction, which requires
the system bus, the LOCK prefix instruction ensures that other processors
connected in the system will not gain the control of the bug. The 8086, while
executing the prefixed instruction, asserts the bus lock signal output, which may
be connected to an external bus controller.
QS 1 , QS 0 -Queue Status These lines give information about the status of the
code-prefetch queue. These are active during the CLK cycle after which the
queue operation is performed. These are encoded as shown in Table below4.
QS 1 QS 0 Indication

0 0 No operation
0 1 First byte of opcode from the queue
1 0 Empty queue
1 1 Subsequent byte from the queue

This modification in a simple fetch and execute architecture of a


conventional microprocessor offers an added advantage of pipelined processing
of the instructions. The 8086 architecture has a 6-byte instruction prefetch queue.
Thus even the largest (6-bytes) instruction can be prefetched from the memory
and stored in the prefetch queue. This results in a faster execution of the
instructions. In 8085, an instruction (opcode and operand) is fetched, decoded

20
Chapter 1 The 8086/8088 MICROPROCESSORS

and executed and only after the execution of this instruction, the next one is
fetched. By prefetching the instruction, there is a considerable speeding up in
instruction execution in 8086. This scheme is known as instruction pipelining.
At the starting the CS:IP is loaded with the required address from
which the execution is to be started. Initially, the queue will be empty and the
microprocessor starts a fetch operation to bring one byte (the first byte) of
instruction code, if the CS:IP address is odd or two bytes at a time, if the CS:IP
address is even. The first byte is a complete opcode in case of some instructions
(one byte opcode instruction) and it is a part of opcode, in case of other
instructions (two byte long opcode instructions), the remaining part of opcode
may lie in the second byte. But invariably the first byte of an instruction is an
opcode. These opcodes along with data are fetched and arranged in the queue.
When the first byte from the queue goes for decoding and interpretation, one
byte in the queue becomes empty and subsequently the queue is updated. The
microprocessor does not perform the next fetch operation till at least two bytes of
the instruction queue are emptied.

21
Chapter 1 The 8086/8088 MICROPROCESSORS

Fig: The Instruction QUEUE Operation


The instruction execution cycle is never broken for fetch operation.
After decoding the first byte, the decoding circuit decides whether the
instruction is of single opcode byte or double opcode byte. If it is single opcode
byte, the next bytes are treated as data bytes depending upon the decoded
instruction length, other- wise, the next byte in the queue is treated as the second
byte of the instruction opcode. The second byte is then decoded in continuation
with the first byte to decide the instruction length and the number of subsequent
bytes to be treated as instruction data. The queue is updated after every byte is
read from the queue but the fetch cycle is initiated by BIU only if at least two
bytes of the queue are empty and the EU may be concurrently executing the
fetched instructions.
The next byte after the instruction is completed is again the first
opcode byte of the next instruction. A similar procedure is repeated till the
complete execution of the program. The main point to be noted here is that the
fetch operation of the next instruction is overlapped with the execution of the
current instruction. As shown in the architecture, there are two separate units,
namely, execution unit and bus interface unit, while the execution unit is busy in
executing an instruction, after it is completely decoded, the bus interface unit
may be fetching the bytes of the next instruction from memory, depending upon
the queue status.
RQ/GT 0 , RQ/GT 1 -Request/Grant
Other local bus masters, in maximum mode, to force the processor to
release the local bus at the end of the processor’s current bus cycle, use these
pins. Each of the pins is bi-directional with RQ/GT 0 having higher priority than
RQ/GT 1 . RQ/GT pins have internal pull-up resistors and may be left
unconnected. The request/ grant sequence is as follows:

22
Chapter 1 The 8086/8088 MICROPROCESSORS

1. A pulse one clock wide from another bus master requests the bus access to
8086.
2. During T4 (current) or T, (next) clock cycle, a pulse one clock wide from
8086 to the requesting master, indicates that the 8086 has allowed the local
bus to float and that it will enter the "hold acknowledge" state at next
clock cycle. The CPU's bus interface unit is likely to be disconnected from
the local bus of the system.
3. A one clock wide pulse from another master indicates to 8086 that the
'hold' request is about to end and the 8086 may regain control of the local
bus at the next clock cycle.
Thus each master-to-master exchange of the local bus is a sequence of 3
pulses. There must be at least one dead clock cycle after each bus exchange. The
request and grant pulses are active low. For the bus requests those are received
while 8086 is performing memory or 1/0 cycle, the granting of the bus is
governed by the rules as discussed in case of HOLD, and HLDA in minimum
mode.
1.4 PHYSICAL MEMORY ORGANISATION
In an 8086 based system, the 1-Mbytes memory is physically organized
as odd bank and even bank, each of 512Kbytes, addressed in parallel by the
processor. Byte data with even address is transferred on D 7 – D 0 , while the byte
data with odd address is transferred on D 15 - D 8 bus lines. The processor provides
two enable signals, BHE and A 0 for selection of either even or odd or both the
banks. The instruction stream is fetched from memory as words and is addressed
internally by the processor as necessary. In other words, if the processor fetches a
word (consecutive two bytes) from memory, there are different possibilities, like:
1. Both the bytes may be data operands.
2. Both the bytes may contain opcode bits.
3. One of the bytes may be opcode while the other may be data.

23
Chapter 1 The 8086/8088 MICROPROCESSORS

Fig: 8086 Memory Banks


All the above possibilities are taken care of by the internal decoder circuit of the
microprocessor. The opcodes and operands are identified by the internal decoder
circuit, which further derives the signals those act as input to the timing and
control unit. The timing and control unit then derives all the signals required for
execution of the instruction.
In referring word data, the BIU requires one or two memory cycles, depending
upon whether the starting byte is located at an even or odd address. It is always
better to locate the word data at an even address. To read or write a complete
word from/to memory, if it is located at an even address, only one read or write
cycle is required. If the word is located at an odd address, the first read or write
cycle is required for accessing the lower byte while the second one is required for
accessing the upper byte. Thus two bus cycles are required, if a word is located at
an odd address. It should be kept in mind that while initializing the structures
like stack they should be initialized at an even address for efficient operation.

24
Chapter 1 The 8086/8088 MICROPROCESSORS

Certain locations in memory are reserved for specific CPU operations.


The locations from FFFF0H to FFFFFH are reserved for operations including
jump to initialization, programme and I/O-processor initialization. The locations
00000H to 003FFH are reserved for interrupt vector table. The interrupt structure
provides space for a total of 256 interrupt vectors. The vectors, i.e. CS and IP for
each interrupt routine requires 4 bytes for storing it in the interrupt vector table.
Hence 256 types of interrupt require 256 x 4 = 03FFH (1Kbyte) locations for the
complete interrupt vector table.
1.5 I/O ADDRESSING CAPABILITY
The 8086/8088 processors can address up to 64K I/O byte registers or 32K
word registers. The limitation is that the address of an I/O device must not be
greater than 16 bits in size; this means that a maximum number of 216 , i.e.
64Kbyte I/O devices may be accessed by the CPU. The I/O address appears on
the address lines A 0 to A 5 for one clock cycle (T 1 ). It may then be latched using
the ALE signal. The upper address lines (A 16 – A 19 ) are at logic 0 level during the
1/0 operations.
The 16-bit register DX is used as 16-bit I/O address pointer, with full
capability to address up to 64K devices. In this case, the I/O ports are addressed
in the same manner as memory locations in the based addressing mode using
BX. In memory mapped I/O interfacing, the I/O device addresses are treated as
memory locations in page 0, i.e. segment address 0000H. Even addressed bytes
are transferred on D 7 -D 0 and odd addressed bytes are transferred on D 8 – D 15
lines. While designing any 8 bit I/O system around 8086, care must be taken that
all the byte registers in the system should be addressed even.
SPECIAL PROCESSOR ACTIVITIES
Processor Reset and Initialization
When logic 1 is applied to the RESET pin of the microprocessor, it is reset
and it remains in the reset state till logic 0 is again applied to the RESET pin. The

25
Chapter 1 The 8086/8088 MICROPROCESSORS

8086 terminate the ongoing operation on the positive edge of the reset signal.
When the negative edge is detected, the reset sequence starts and is continued for
nearly 10 clock cycles. During this period, all the internal register contents are set
to 0000H except CS is set to value F000H and IP to value FFF0H. Thus the
execution again starts from the physical address FFFF0H. Due to this, the
EPROM in an 8086 system is interfaced so as to have the physical memory
locations FFFF0H to FFFFFH in it, i.e. at the end of the map.
For the reset signal to be accepted by 8086, it must be high for at least 4
clock cycles. From the instant the power is on, the reset pulse should not be
applied to 8086 before 50,us to allow proper initialization of 8086. In the reset
state, all the 3-state outputs are tristated. Status signals are active in idle state for
the first clock cycle after the reset becomes active, and then floats to tristate. The
ALE and HLDA lines are driven low during the reset operation.
Non-maskable interrupt enable request, which appears before the second
clock after the end of the reset operation, will not be served. For the NMI request
to be served, it must appear after the second clock cycle during reset initialisation
or later. If a HOLD request appears immediately after RESET, it will be
immediately served after initialisation, before execution of any instruction.
HALT
When the processor executes a HLT instruction, it enters the 'halt' state.
Before entering 'halt' state, it indicates that it is entering 'halt' state in two ways,
depending upon whether it is in minimum or maximum mode. When the
processor is in minimum mode and wants to enter halt state, it issues an ALE
pulse but does not issue any control signal. When the processor is in maximum
mode and wants to enter halt state, it puts the HALT status on S 2 , S 1 and S 0 pins
and then the bus controller issues one ALE pulse but no qualifying signal, i.e. no
appropriate address or control signals are issued onto the bus. Only an interrupt

26
Chapter 1 The 8086/8088 MICROPROCESSORS

request or reset will force the 8086 to come out of the 'halt' state. Even the HOLD
request cannot force the 8086 out of 'halt' state.
TEST and Synchronization with External Signals
Besides the interrupt, hold and general I/O capabilities, the 8086 has an
extra facility of the TEST signal. When the CPU executes a WAIT instruction, the
processor preserves the contents of the registers, before execution of the WAIT
instruction, and the CPU waits for the TEST input pin to go low. If the TEST pin
goes low, it continues further execution; otherwise, it keeps on waiting for the
TEST pin to go low. For the TEST signal to be accepted, it must be low for at least
5 clock cycles. The activity of waiting does not consume any bus cycle. The
processor remains in idle state while waiting. While waiting, any 'HOLD' request
from an external device may be served. If an interrupt occurs when the processor
is waiting, it fetches the wait instruction once more, executes it, and then serves
the interrupt. After returning from the interrupt, it fetches the wait instruction
once more and continues with the 'wait' state.
Thus the execution of the portion of a program, which appears in the
program after WAIT instruction can be synchronized with an external signal
connected with the TEST input.
1.6. THE PROCESSOR 8088
The launching of the processor 8086 is seen as a remarkable step in the
development of high speed computing machines. Before the introduction of 8086,
most of the circuits required for the different applications in computing and
industrial control fields were already designed around the 8-bit processor 8085.
The 8086 imparted tremendous flexibility in the programming as compared to
8085. So naturally, after the introduction of 8086, there was a search for a
microprocessor chip which has the programming flexibility like 8086 and the
external interface like 8085, so that all the existing circuits built around 8085 can
work as before, with this new chip. The chip 8088 was a result of this demand.

27
Chapter 1 The 8086/8088 MICROPROCESSORS

The microprocessor 8088 has all the programming facilities that 8086 has, along
with some hardware features of 8086, like 1-Mbyte memory addressing
capability, operating modes (MN/MX), interrupt structure etc. However 8088,
unlike 8086, has 8-bit data bus. This feature of 8088 makes the circuits, designed
around 8085, compatible with 8088, with little or no modification.
All the peripheral interfacing schemes with 8088 are the same as those for
the 8-bit processors. The memory and I/O addressing schemes are now exactly
similar to 8085 schemes except for the increased memory (1-Mbyte) and I/O
(64Kbyte) capabilities. The architecture shows the developments in 8088 over
8086.
Architecture of 8088: The register set of 8088 is exactly the same as in to 8086.
The architecture of 8088 is also similar to 8086 except for two changes;
a) 8088 has 4-byte instruction queue and
b) 8088 has 8-bit data bus.
The function of each block is the same as in 8086.
The addressing capability of 8088 is 1-Mbyte; therefore, it needs 20
address bits, i.e. 20 addressing lines. While handling this 20-bit address, the
segmented memory scheme is used and the complete physical address forming
procedure is the same as explained in case of 8086. While physically interfacing
memory to 8088, there is nothing like an even address bank or odd address bank.
The complete memory is homogeneously addressed as a bank of 1-Mbyte
memory locations using the segmented memory scheme. This change in
hardware is completely transparent to soft- ware. As a result of the modified
data bus, the 8088 can access only a byte at a time. This fact reduces the speed of
operation of 8088 as compared to 8086, but the 8088 can process the 16-bit data
internally. On account of this change in bus structure, the 8088 has slightly
different timing diagrams than 8086.

28
Chapter 1 The 8086/8088 MICROPROCESSORS

1.7. Comparison between 8086 and 8088


The 8088, with an 8-bit external data bus, has been designed for internal
16-bit processing capability. Nearly all the internal functions of 8088 are identical
to 8086. The 8088 uses the external bus in the same way as 8086, but only 8 bits of
external data are accessed at a time. While fetching or writing the 16-bit data, the
task is performed in two consecutive bus cycles. As far as the software is
concerned, the chips are identical, except in case of timings. The 8088, thus may
take more time for execution of a particular task as compared to 8086.
All the changes in 8088 over 8086 are directly or indirectly related to the 8-
bit, 8085 compatible data and control bus interface.
1. The pre-decoded code queue length is reduced to 4 bytes in 8088, whereas
the 8086 queue contains 6 bytes. This was done to avoid the unnecessary
prefetch operations and optimize the use of the bus by BIU while
prefetching the instructions.
2. The 8088-bus interface unit will fetch a byte from memory to load the
queue each time, if at least 1 byte is free. In case of 8086, at least 2 bytes
should be free for the next fetch operation.
3. The 8-bit external data bus affects the overall execution time of the
instructions in 8088. All the 16-bit operations now require additional 4
clock cycles. The CPU speed is also limited by the speed of instruction
fetches.
The pin assignments of both the CPUs are nearly identical, however, they have
the following functional changes.
1. A 8 – A 15 already latched, all time valid address bus.
2. BHE has no meaning as the data bus is of 8-bits only.
3. SS 0 provides the S 0 status information in minimum mode.
4. IO/M has been inverted to be compatible with 8085 bus structure.

29
Chapter 1 The 8086/8088 MICROPROCESSORS

1.8. The Minimum and Maximum Modes


The logic level applied to the MN/MX input, pin 33, determines the
operating mode of the 8086. If pin 33 is asserted high, then the 8086 will function
in minimum mode, and pins 24 through 31 will have the functions shown in
parentheses next to the pins in the pin diagram. In the minimum mode, for
example, pin 29 will function as WR, which will go low any time the 8086 writes
to a port or to a memory location. The RD, WR, and M/IO signals form the heart
of the control bus for a minimum mode 8086 system. The 8086 is operated in
minimum mode in systems such as the SDK-86/EV-Z2 where it is the only
microprocessor on the system buses.
If the MN/MX pin is asserted low, then the 8086 is in maximum mode. In
this mode, pins 24 through 31 will have the functions described by the
mnemonics next to the pins in the pin diagram. In this mode, the control bus
signals (S0, S1, and S2) are sent out in encoded form on pins 26, 27, and 28. An
external bus controller device decodes these signals to produce the control bus
signals required for a system, which has two or more microprocessors sharing
the same buses.
1.9. WHAT IS THE NEED FOR SEGMENTATION?
At this point you may be wondering why Intel designed the 8086 family
devices to access memory using the segment: offset approach rather than
accessing memory directly with 20-bit addresses. The segment: offset, scheme
requires only a 16-bit number to represent the base address for a segment, and
only a 16-bit offset to access any location in a segment. This means that the 8086
has to manipulate and store only 16-bit quantities instead of 20-bit quantities.
This makes for an easier interface with 8- and 16-bit-wide memory boards and
with the 16-bit registers in the 8086.
The second reason for segmentation has to do with the type of
microcomputer in which an 8086-family CPU is likely to be used. In a

30
Chapter 1 The 8086/8088 MICROPROCESSORS

timesharing system, several users share a CPU. The CPU works on one user's
program for perhaps 20 ms, then works on the next user's program for 20 ms.
After working 20 ms for each of the other users, the CPU comes back to the first
user's program again. Each time the CPU switches from one user's program to
the next, it must access a new section of code and new sections of data.
Segmentation makes this switching quite easy. Each user's program can be
assigned a separate set of logical segments for its code and data. The user's
program will contain offsets or displacements from these segment bases. To
change from one user's program to a second user's program, all that the CPU has
to do is to reload the four segment registers with the segment base addresses
assigned to the second user's program. In other words, segmentation makes it
easy to keep users’ programs and data separate from one another, and
segmentation makes it easy to switch from one user's program to another user's
program.

31
Chapter 2 Assembly Language Programming

CHAPTER

ASSEMBLY LANGUAGE PROGRAMMING


OF THE MICROCOMPUTER

2.1 Introduction
To run a program, a microcomputer must have the program stored in binary
form in successive memory locations. There are three language levels that can be
used to write a program for a microcomputer.
Machine Language:
We can write programs as simply a sequence of the binary codes for the
instructions we want the micro- computer to execute. The binary form of the
program is referred to as machine language because it is the form required by the
machine. However, it is difficult, if not impossible, for a programmer to
memorize the thousands of binary instruction codes for a CPU such as the 8086.
Also, it is very easy for an error to occur when working with long series of 1's
and 0's. Using hexadecimal representation for the binary codes might help some,
but there are still thousands of instruction codes to cope with.
Assembly Language:
To make programming easier, many programmers write programs in
assembly language. They then translate the assembly language program to
machine language so that it can be loaded into memory and run. Assembly
language uses two-, three-, or four-letter mnemonics to represent each
instruction type. A mnemonic is just a device to help us to remember something.
The letters in an assembly language mnemonic are usually initials or a shortened
form of the English word(s) for the operation performed by the instruction. For
example, the mnemonic for subtract is SUB, the mnemonic for Exclusive OR is
XOR, and the mnemonic for the instruction to copy data from one location to
another is MOV.
High Level Languages:
Another way of writing program for a microcomputer is with high-level
languages such as BASIC, C, JAVA or C++. These languages use program
statements, which are even more English-like than those of assembly language.
Each high-level statement may represent many machine code instructions. An
interpreter program or a compiler program is used to translate higher-level
language statements to machine codes, which can be loaded into memory and
executed.

2
Chapter 2 Assembly Language Programming

2.2. Addressing Modes Of 8086


Addressing mode indicates a way of locating data or operands.
Depending upon the data types used in the instruction and the memory
addressing modes, any instruction may belong to one or more addressing modes,
or some instruction may not belong to any of the addressing modes. Thus the
addressing modes describe the types of operands and the way they are accessed for
executing an instruction.
The addressing mode depends upon the operands and suggests how the
effective address may be computed for locating the operand, if it lies in memory.
The different addressing modes of the 8086 instructions are listed in Table 2.2.
Table 2.2 Different Ways of Accessing Memory Operands

Note:
1. D8 and D16 represent 8 and 16 bit displacements respectively.
2. The default segment for the addressing modes using BP and SP is SS. For all other addressing modes the
default segments are DS or ES.
When a data is to be referred as an operand, DS is the default data segment
register. CS is the default code segment register for storing program codes
(executable codes) . SS is the default segment register for the stack data accesses
and operations. ES is the default segment register for the destination data
storage. All the segments available (defined in a particular program) can be read
or written as data segments by newly defining the data segment as required.
There is no physical difference in the memory structure or no physical separation
between the segment areas. They may or may not overlap with each other.
According to the flow of instruction execution, the instructions may be
categorized as (i) Sequential control flow instructions and (ii) Control transfer
instructions.
Sequential control flow instructions are the instructions, which after
execution, transfer control to the next instruction appearing immediately after it
(in the sequence) in the pro- gram. For example, the arithmetic, logical, data
transfer and processor control instructions are sequential control flow
instructions. The control transfer instructions, on the other hand, transfer control

3
Chapter 2 Assembly Language Programming

to some predefined address or the address somehow specified in the instruction,


after their execution. For example, INT, CALL, RET and JUMP instructions fall
under this category.
The addressing modes for sequential control transfer instructions are explained
as follows:
1. Immediate : In this type of addressing, immediate data is a part of instruction,
and appears in the form of successive byte or bytes.
Example MOV AX, 0005H
In the above example, 0005H is the immediate data. The immediate data may be
8-bit or 16-bit in size.
2. Direct : In the direct addressing mode, a 16-bit memory address (offset) is
directly specified in the instruction as a part of it.
Example MOV AX, [5000H]
Here, data resides in a memory location in the data segment, whose effective
address may be computed using 5000H as the offset address and content of DS as
segment address. The effective address, here, is 10H*DS+5000H.
3. Register : In register addressing mode, the data is stored in a register and it is
referred using the particular register. All the registers, except IP, may be used in
this mode.
Example MOV BX, AX.
4. Register Indirect : Sometimes, the address of the memory location, which
contains data or operand, is determined in an indirect way, using the offset
registers. This mode of addressing is known as register indirect mode. In this
addressing mode, the offset address of data is in either BX or SI or DI registers.
The default segment is either DS or ES. The data is supposed to be available at
the address pointed to by the content of any of the above registers in the default
data segment.
Example MOV AX, [BX]
Here, data is present in a memory location in DS whose offset address is
in BX. The effective address of the data is given as 10H*DS+[BXI.
5. Indexed : In this addressing mode, offset of the operand is stored in one of the
index registers. DS and ES are the default segments for index registers SI and DI
respectively. This mode is a special case of the above discussed register indirect
addressing mode.
Example MOV AX, [SI]
Here, data is available at an offset address stored in SI in DS. The effective
address, in this case, is computed as 10H*DS+[SI].
6. Register Relative: In this addressing mode, the data is available at an effective
address formed by adding an 8-bit or 16-bit displacement with the content of any
one of the registers
BX, BP, SI and DI in the default (either DS or ES) segment. The example given
below explains this mode.

4
Chapter 2 Assembly Language Programming

Example MOV AX, 50H [BX]


Here, the effective address is given as 10H*DS+50H+[BX].
7. Based Indexed: The effective address of data is formed, in this addressing
mode, by adding content of a base register (any one of BX or BP) to the content of
an index register (any one of SI or DI). The default segment register may be ES or
DS.
Example MOV AX, [BXI [SI]
Here, BX is the bass register and SI is the index register. The effective address is
computed as 10H*DS+[BX]+[SI].
8. Relative Based Indexed: The effective address is formed by adding an 8 or 16-
bit displacement with the sum of contents of any one of the base registers (BX or
BP) and any one of the index registers, in a default segment.
Example MOV AX, 50 H [BX] [SI]
Here, 50H is an immediate displacement, BX is a base register and SI is an
index register. The effective address of data is computed as 10H*DS+ [BXI+ [SI]
+50H.

2.3 INSTRUCTION SET OF 8086/8088

2.3.1 Classification of Instruction:


The 8086/8088 instructions are categorized into the following main types.
This section explains the function of each of the instructions with suitable
examples wherever necessary.
(1) Data Transfer Instructions. This type of instructions is used to transfer data
from source operand to destination operand. All the store, move, load, exchange,
input and output instructions belong to this category.
Under this category there are following group of instructions

General-Purpose Byte or Word Transfer Instructions:


MOV Copy byte or word from specified source to specified destination.
PUSH Copy specified word to top of stack.
POP Copy word from top of stack to specified location.
XCHG Exchange bytes or exchange words.
XLAT Translate a byte in AL using a table in memory.
Simple Input Output Port Transfer Instructions:
IN Copy a byte or word from specified port to accumulator.
OUT Copy a byte or word from accumulator to specified port.
Special Address Transfer Instructions:
LEA Load effective address of operand into specified register.
LDS Load DS register and other specified register from memory.
LES Load ES register and other specified register from me
Flag Transfer Instructions:

5
Chapter 2 Assembly Language Programming

LAHF Load (copy to) AH with the low byte of the flag register.
SAHF Store (copy) AH register to low byte of flag register.
PUSHF Copy flag register to top of stack.
POPF Copy word at top of stack to flag register.
(2) Arithmetic Instructions. Under this category there are following group of
instructions
Addition Instructions:
ADD Add specified byte-to-byte or specified word to word.
ADC Add byte + byte + carry flag or word + word + carry flag.
INC Increment specified byte or specified word by 1.
AAA ASCII adjust after addition.
DAA Decimal (BCD) adjust after addition.
Subtraction Instructions:
SUB Subtract byte from byte or word from word.
SBB Subtract byte and carry flag from byte or word and carry flag from word.
DEC Decrement specified byte or specified word by 1.
NEG Negate-Invert each bit of a specified byte or word and add 1 (form 2's
complement).
CMP Compare two specified bytes or two specified words.
AAS ASCII adjust after subtraction.
DAS Decimal (BCD) adjust after subtraction.
Multiplication Instructions:
MUL Multiply unsigned byte-by-byte or unsigned word by word.
IMUL Multiply signed byte by byte or signed word by word.
AAM ASCII adjust after multiplication.
Division Instructions:
DIV Divide unsigned word by byte or unsigned double word by word.
IDIV Divide signed word by byte or signed double word by word.
AAD ASCII adjust before division.
CBW Fill upper byte of word with copies of sign bit of lower byte.
CWD Fill upper word of double word with sign bit of lower word.
(3) Bit Manipulation Instructions. Under this category there are following group
of instructions
Logical Instructions:
NOT Invert each bit of a byte or word.
AND AND each bit in a byte or word with the corresponding bit in
another byte or word.
OR OR each bit in a byte or word with the corresponding bit in another
byte or word.
XOR Exclusive OR each bit in a byte or word with the corresponding bit
in another byte or word.
TEST AND operands to update flags, but don't change operands.

6
Chapter 2 Assembly Language Programming

Shift Instructions:
SHL/SAL Shift bits of word or byte left, put zero(s) in LSB(s).
SHR Shift bits of word or byte right, put zero(s) in MSB(s).
SAR Shift bits of word or byte right, copy old MSB into new MSB
Rotate Instructions:
ROL Rotate bits of byte or word left, MSB to LSB and to CF.
ROR Rotate bits of byte or word right, LSB to MSB and to CF.
RCL Rotate bits of byte or word left, MSB to CF and CF to LSB.
RCR Rotate bits of byte or word right, LSB to CF and CF to MSB.
(4) String Instructions: A string is a series of bytes or a series of words in
sequential memory locations. A string often consists of ASCII character codes. In
this list, a ‘/’ is used to separate different mnemonics for the same instruction.
Use the mnemonic, which most clearly describes the functions of the instruction
in a specific application. A ‘B’ in a mnemonic is used to specifically indicate that
a string of bytes is to be acted upon. A ‘W’ in the mnemonic is used to indicate
that a string of words is to be acted upon.
REP An instruction prefix. Repeat following instruction until CX = 0.
REPE/REPZ An instruction prefix. Repeat instruction until CX = 0 or zero flag
ZF  1.
REPNE/REPNZ An instruction prefix. Repeat until CX = 0 or ZF = 1.
MOVS/MOVSB/MOVSW Move byte or word from one string to another.

COMPS/COMPSB/COMPSW Compare two string bytes or two string words.


SCAS/SCASB/SCASW Scan a string. Compare a string byte with a byte
in AL or a string word with a word in AX.
LODS/LODSB/LODSW Load string byte into AL or string word into AX.
STOS/STOSB/STOSW Store byte from AL or word from AX into string.
(5) Program Execution Transfer Instructions: These instructions are used to tell
the 8086 to start fetching instructions from some new address, rather than
continuing in sequence. It contains the following group of instructions.
Unconditional Transfer Instructions:
CALL Call a procedure (subprogram), save return address on stack.
RET Return from procedure to calling program.
JMP Go to specified address to get next instruction.
Conditional Transfer Instructions:
A ‘/ ‘is used to separate two mnemonics which represent the same
Instruction. Use the mnemonic, which most clearly describes the decision
condition in a specific program. These instructions are often used after a compare
instruction. The terms below and above refer to unsigned binary numbers.
Above means larger in magnitude. The terms greater than or less than refer to
signed binary numbers. Greater than means more positive.
JA/JNBE Jump if above/jump if not below or equal.

7
Chapter 2 Assembly Language Programming

JAE/JNB Jump if above or equal/jump if not below.


JB/JNAE Jump if below/jump if not above or equal.
JBE/JNA Jump if below or equal/jump if not above.
JC Jump if carry flag CF = 1.
JE/JZ Jump if equal/jump if zero flag ZF = 1.
JG/JNLE Jump if greater/jump if not less than or equal.
JGE/JNL Jump if greater than or equal/ Jump if not less than.
JL/JNGE Jump if less than/jump if not greater than or-equal.
JLE/JNG Jump if less than or equal/jump if not greater than.
JNC Jump if no carry (CF = 0).
JNE/JNZ Jump if not equal/jump if not zero (ZF = 0).
JNO Jump if no overflow (overflow flag OF = 0).
JNP/JPO Jump if not parity/jump if parity odd (PF = 0).
JNS Jump if not sign (sign flag SF= 0).
JO Jump if overflow flag OF = 1.
JP/JPE Jump if parity/jump if parity even (PF = 1).
JS Jump if sign (SF
Iteration Control Instructions:
These instructions can be used to execute a series of instructions some
number of times. Here mnemonics separated by a "/ " represent the same
instruction. Use the one that best fits the specific application.
LOOP Loop through a sequence of instructions until CX = 0.
LOOPE/LOOPZ Loop through a sequence of instructions while ZF =1 and CX
 0.
LOOPNE/LOOPNZ Loop through a sequence of instructions while ZF = 0 and
CX  0.
JCXZ Jump to specified address if CX = 0.
Interrupt Instructions:
INT Interrupt program execution, call service procedure.
INTO Interrupt program execution if OF = 1.
IRET Return from interrupt service procedure to main program.
(6) Processor Control Instructions: This category includes the following groups
of instructions.
Flag Set/clear Instructions:
STC Set carry flag CF to 1.
CLC Clear carry flag CF to 0.
CMC Complement the state of the carry flag CF.
STD Set direction flag DF to 1 (decrement string pointers).
CLD Clear direction flag DF to 0.
STI Set interrupt enable flag to 1 (enable INTR input).
CLI Clear interrupt enable flag to 0 (disable INTR input).

8
Chapter 2 Assembly Language Programming

External Hardware Synchronization Instructions:


HLT Halt (do nothing) until interrupt or reset.
WAIT Wait (do nothing) until signal on the TEST pin is low.
ESC Escape to external coprocessor such as 8087 or 8089
LOCK An instruction prefix. Prevents another processor from
taking the bus
No Operation Instruction:
NOP No action except fetch and decode.

DETAILED DISCUSSION ON INSTRUCTIONS


2.4.2 Data Transfer Instructions
2.3.2.1 General-Purpose Byte Or Word Transfer Instructions:

MOVǦǦǦCopyaWordorByteǦǦǦMOVDestination,Source
The MOV instruction copies a word or byte of data from a specified
source to a specified destination. The destination can be a register or a memory
location. The source can be a register, a memory location, or an immediate
number. The source and destination in an instruction cannot both be memory
locations. The source and destination in a MOV instruction must both be of type
byte, or they must both be of type word. MOV instructions do not affect any
flags.
EXAMPLES:
MOV CX, 037AH Put the immediate number 037AH in CX
MOV BL, [437AH] Copy byte in DS at offset 437AH to BL
MOV AX, BX Copy contents of register BX to AX
MOV DL, [BX] Copy byte from memory at [BX] to DL.
MOV DS, BX Copy word from BX to DS register
MOV RESULTS[BP],AX Copy AX to two memory locations-AL to the first
location, AH to the second. EA of the first memory location is the sum of the
displacement represented by RESULTS and contents of BP. Physical address =
EA + SS.
MOV CS:RESULTS[BP],AX Same as the above instruction, but physical
address = EA + CS because of the segment override prefix CS.

PUSHǦPUSHSource
The PUSH instruction decrements the stack pointer by 2 and copies a
word from a specified source to the location in the stack segment where the stack
pointer then points. The source of the word can be a general- purpose register, a
segment register, or memory. The stack segment register and the stack pointer
must be initialized before this instruction can be used. PUSH can be used to save
data on the stack so that it will not be destroyed by a procedure. It can also be
used to put data on the stack so that a procedure can access it there as needed.
No flags are affected by this instruction.

9
Chapter 2 Assembly Language Programming

EXAMPLES:
PUSH BX Decrement SP by 2, copy BX to stack
PUSH DS Decrement SP by 2, copy DS to stack
PUSH AL Illegal, must push a word
PUSH TABLE [BX] Decrement SP by 2, copy word from memory in DS
at EA = TABLE + [BX] to stack

POPǦPOPDestination
The POP instruction copies a word from the stack location pointed to by
the stack pointer to a destination specified in the Instruction. The destination can
be a general-purpose register, a segment register, or a memory location. The data
in the stack is not changed. After the word is copied to the specified destination,
the stack pointer is automatically incremented by 2 to point to the next word on
the stack. No flags are affected by the POP instruction.
NOTE: POP CS is illegal.
EXAMPLES:
POP DX Copy a word from top of stack to DX Increment SP by 2
POP DS Copy a word from top of stack to DS Increment SP by 2
POP TABLE [BX] Copy a word from top of stack to memory in DS
with EA = TABLE +[BX]

XCHGǦXCHGDestination,Source
The XCHG instruction exchanges the contents of a register with the
contents of another register or the contents of a register with the contents of a
memory locations). The XCHG cannot directly exchange the contents of two
memory locations. A memory location can be specified as the source or as the
destination by any of the 24 addressing modes. The source and destination must
both be words, or they must both be bytes. The segment registers cannot be used
in this instruction. No flags are affected by this instruction.
EXAMPLES:
XCHG AX,DX Exchange word in AX with word in DX
XCHG BL,CH Exchange byte in BL with byte in CH
XCHG AL,PRICES [BX] Exchange byte in AL with byte in memory at
EA = PRICES [BX] in DS

XLAT/XLATBǦTranslateaByteinAL
The XLATB instruction is used to translate a byte from one code to
another code. The instruction replaces a byte in the AL register with a byte
pointed to by BX in a lookup table in memory. Before the XLATB instruction can
be executed, the lookup table containing the values for the new code must be put
in memory, and the offset of the starting address of the lookup table must be
loaded in BX. The code byte to be translated is put in AL. To point to the desired
byte in the lookup table, the XLATB instruction adds the byte in AL to the offset

10
Chapter 2 Assembly Language Programming

of the start of the table in BX. It then copies the byte from the address pointed to
by (BX + AL) back into AL. XLATB changes no flags.
EXAMPLE:
8086 routine to convert ASCII code byte to EBCDIC equivalent.
ASCII code byte is in AL at start. EBCDIC code in AL at end.
MOV BX,OFFSET EBCDIC_TABLE
Point BX at start of EBCDIC table in DS
XLATB Replace ASCII in AL with EBCDIC from table
The XLATB instruction can be used to convert any code of 8 bits or less to any
other code of 8 bits or less.

2.3.2.2. Simple Input Output Port Transfer Instructions:

INǦCopyDatafromaPortǦǦINAccumulator,Port
The IN instruction will copy data from a port to the AL or AX register. If
an 8-bit port is read, the data will go to AL. If a 16-bit port is read, the data will
go to AX. The IN instruction has two possible formats, fixed port and variable
port.
For the fixed-port type, the 8-bit address of a port is specified directly in
the instruction.
EXAMPLES:
IN AL, 0C8H Input a byte from port 0C8H to AL
IN AX,34H Input a word from port 34H to AX
A_TO_D EQU 4AH
IN AX,A_TO_D Input a word from port 4AH to AX
For the variable-port-type IN instruction, the port address is loaded into
the DX register before the IN instruction. Since DX is a 16-bit register, the port
address can be any number between 0000H and FFFFH. Therefore, up to 65,536
ports are addressable in this mode.
MOV DX, 0FF78H Initialize DX to point to port
IN AL, DX Input a byte from 8-bit port 0FF78H to AL
IN AX, DX Input a word from 16-bit port 0FF78H to AX
The variable-port IN instruction has the advantage that the port address can be
computed or dynamically determined in the program.
OUTǦOutputaByteorWordtoaPortǦǦOUTPort,AccumulatorALorAX
The OUT instruction copies a byte from AL or a word from AX to the
specified port. The OUT instruction has two possible forms, fixed port and
variable port.
For the fixed-port form, the 8-bit port address is specified directly in the
instruction. With this form, any one of 256 possible ports can be addressed.
EXAMPLES:
OUT 3BH,AL Copy the contents of AL to port 3BH

11
Chapter 2 Assembly Language Programming

OUT 2CH,AX Copy the contents of AX to port 2CH For the variable-port form
of the OUT instruction, the contents of AL or AX will be copied to the port at an
address contained in DX. Therefore, the DX register must always be loaded with
the desired port address before this form of the OUT instruction is used. The
advantage of the variable-port form of addressing is described in the discussion
of the IN instruction. The OUT instruction does not affect any flags.
MOV DX, 0FFF8H Load desired port address in DX
OUT DX, AL Copy contents of AL to port FFF8H
OUT DX, AX Copy contents of AX to port FFF8H

2.3.2.3. Special Address Transfer Instructions:

LEAǦLoadEffectiveAddressǦLEARegister,Source
This instruction determines the offset of the variable or memory location
named as the source and puts this offset in the indicated 16-bit register. LEA
changes no flags.
EXAMPLES:
LEA BX, PRICES Load BX with offset of PRICES in DS
LEA BP, SS: STACK_TOP Load BP with offset of STACK_TOP in SS
LEA CX, [BX][DI] Load CX with EA = (BX) + (DI)
Assume PRICES is an array of bytes in a segment called ARRAYS. The
instruction LEA BX, PRICES will load the displacement of the first element of
PRICES directly into BX. The instruction MOV AL,[BX] can then be used to bring
an element from the array into AL.

LDSǦLoadRegisterandDSwithWordsfromMemoryǦLDSRegister,Memory
AddressofFirstWord
This instruction copies a word from two memory locations into the
register specified in the instruction. It then copies a word from the next two
memory locations into the DS register. LDS is useful for pointing SI and DS at the
start of a string before using one of the string instructions, LDS affects no flags.
EXAMPLES:
LDS BX, [4326] Copy contents of memory at displacement 4326H in DS to
BL, contents of 4327H to BH. Copy contents at displacement of 4328H and 4329H
in DS to DS register.
LDS SI, STRING_POINTER Copy contents of memory at displacements
STRING_POINTER and STRING_POINTER+1 in DS to SI register. Copy
contents of memory at displacements STRING_POINTER+2 and STRING
POINTER+3 In DS to DS register. DS:SI now points at start of desired string.
LES-Load Register and ES with Words from Memory-LES Register, Memory Address of
First Word
This instruction loads new values into the specified register and into the
ES register from four successive memory locations. The word from the first two

12
Chapter 2 Assembly Language Programming

memory locations is copied into the specified register, and the word from the
next two memory locations is copied into the ES register. LES can be used to
point DI and ES at the start of a string before a string instruction is executed. LES
affects no flags.
EXAMPLES:
LES BX, [789AH] Contents of memory at displacements 789AH and 789BH In
DS copied to BX. Contents of memory at displacements 789CH and 789DH in DS
copied to ES register.
LES DI, [BX] Copy contents of memory at offset [BX] and offset [BX+1] in
DS to DI register. Copy contents of memory at offsets [BX + 2] and [BX + 3] to ES
register.

2.3.2.4. Flag Transfer Instructions


LAHF-Copy Low Byte of Flag Register to AH
The lower byte of the 8086 flag register is the same as the flag byte for the
8085. LAHF copies these 8085 equivalent flags to the AH register. They can then
be pushed onto the stack along with AL by a PUSH AX instruction. An LAHF
instruction followed by a PUSH AX instruction has the same effect as the 8085
PUSH PSW instruction. The LAHF instruction was included in the 8086
instruction set so that the 8085 PUSH PSW instruction could easily be simulated
on an 8086. LAHF changes no flags.

SAHFǦCopyAHRegistertoLowByteofFlagRegister
The lower byte of the 8086 flag register corresponds exactly to the 8085
flag byte. SAHF replaces this 8085 equivalent flag byte with a byte from the AH
register. SAHF is used with the POP AX instruction to simulate the 8085 POP
PSW instruction. As described under the heading LAHF, an 8085 PUSH PSW
instruction will be translated to an LAHF--PUSH AX sequence to run on an 8086.
An 8085 POP PSW instruction will be translated to a POP AX--SAHF sequence to
run on an 8086. SAHF changes the flags in the lower byte of the flag register.

PUSHFǦPushFlagRegisterontheStack
This instruction decrements the stack pointer by 2 and copies the word In
the flag register to the memory locations pointed to by the stack pointer. The
stack segment register is not affected. No flags are changed.

POPFǦPopWordfromTopofStacktoFlagRegister
This instruction copies a word from the two memory locations at the top
of the stack to the flag register and increments the stack pointer by 2. The stack
segment register and the word on the stack are not affected. AU flags are
affected.

13
Chapter 2 Assembly Language Programming

2.3.3 Arithmetic Instructions


2.3.3.1. Addition Instructions
ADC-Add with Carry-ADC Destination, Source
ADD-Add-ADD Destination, Source
These instructions add a number from some source to a number from
some destination and put the -result in the specified destination. The Add with
Carry instruction, ADC, also adds the status of the carry flag into the result. The
source may be an immediate number, a register, or a memory location specified
by any one of the 24 addressing modes. The destination may be a register or a
memory location specified by any one of the 24 addressing modes. The source
and the destination in an instruction cannot both be memory locations. The
source and the destination must be of the same type. In other words, they must
both be byte locations, or they must both be word locations. If we want to add a
byte to a word, we must copy the byte to a word location and fill the upper byte
of the word with 0's before adding. Flags affected: AF, CF, OF, PF, SF, ZF.
EXAMPLES:
ADD AL, 74H Add immediate number 74H to contents of AL. Result In AL
ADC CL, BL Add contents of BL plus carry status to contents of CL.
ADD DX, BX Add contents of BX to contents of DX
ADD DX,[SI] Add word from memory at offset [SI]in DS to contents of DX
ADC AL, PRICES [BX] Add byte from effective address PRICES [BX] plus
carry status to contents of AL
ADD PRICES [BX], AL Add contents of AL to contents of memory location at
effective address PRICES[BX]

Additionofunsignednumbers
CL = 01110011 = 115 decimal
+ BL = 01001111 = 79 decimal
ADD CL, BL Result in CL = 11000010= 194 decimal

Additionofsignednumbers
CL = 01110011 = + 115 decimal
+ BL = 0 100 1111 + 79 decimal
ADD CL, BL Result in CL= 11000010 =62 decimal - incorrect because
result too large to fit in 7 bits.

      


CF = 0 No carry out of bit 7.
PF = 0 Result has odd parity.
AF = 1 Carry was produced out of bit 3.
ZF = 0 Result in destination was not 0.
SF = 1 Copies most significant bit of result; indicates negative result if we are
adding signed numbers.

14
Chapter 2 Assembly Language Programming

OF= 1 Set to indicate that the result of the addition was too large to fit in the
lower 7 bits of the destination used to represent the magnitude of a signed
number. In other words, the result was greater than + 127 decimal, so the result
overflowed into the sign bit position and incorrectly indicated that the result was
negative. If we are adding two signed 16-bit values, the OF will be set if the
magnitude of the result is too large to fit in the lower 15 bits of the destination.
NOTE: PF is meaningful only for an 8-bit result. AF is set only by a carry out of
bit 3. Therefore, the DAA instruction cannot be used after word additions to
convert the result to correct BCD.

INC-increment-INC Destination
The INC instruction adds1to a specified register or to a memory location
specified in any one of the 24 ways. AF, OF, PF, SF, and ZF are affected
(updated) by this instruction. Note that the carry flag (CF) is not affected. This
means that if an 8-bit destination containing FFH or a 16-bit destination
containing FFFFH is incremented, the result will be all 0's with no carry.
EXAMPLES:
INC BL Add 1 to contents of BL register
INC CX Add1to contents of CX register
INC BYTE PTR [ BX] Increment byte in data segment at offset contained in
BX. The BYTE PTR directive is necessary to tell the assembler to put in the right
code to indicate that a byte in memory, rather than a word, is to be incremented.
The instruction essentially says, "Increment the byte pointed to by the contents of
BX."
INC WORD PTR [BX] Increment the word at offset of [BX] and [BX + 1] in
the data segment. In other words, increment the word in memory pointed to by
BX.
INC MAX_TEMPERATURE Increment byte or word named MAX-
TEMPERATURE in data segment. Increment byte if MAX_TEMPERATURE
declared with DB. Increment word if MAX-TEMPERATURE declared with DW.

INC PRICES [BX] Increment element pointed to by [BX] in array PRICES.


Increment a word if PRICES was defined as an array of words with a DW
directive. Increment a byte if PRICES was defined as an array of bytes with a DB
directive.
NOTE: The PTR operator is not needed in the last two examples because the assembler
knows the type of the operand from the DB or DW used to declare the named data
initially.

15
Chapter 2 Assembly Language Programming

AAAǦASCIIAdjustforAddition
Numerical data coming into a computer from a terminal is usually in
ASCII code. In this code, the numbers 0 to 9 are represented by the ASCII codes
30H to 39H. The 8086 allows we to add the ASCII codes for two decimal digits
without masking off the "3" in the upper nibble of each. After the addition, the
AAA Instruction is used to make sure the result is the correct unpacked BCD; A
simple numerical example will show how this works.
EXAMPLE:
Assume AL = 0 0 1 1 0 1 0 1, ASCII 5
BL = 0 0 1 1 1 0 0 1, ASCII 9
ADDAL,BL Result: AL= 0 1 1 0 1 1 1 0 = 6EH,which is incorrect BCD
AAA Now AL = 00000100, unpacked BCD 4.
CF = 1 indicates answer is 14 decimal
NOTE: OR AL with 30H to get 34H, the ASCII code for 4, if we want to send the
result back to a CRT terminal. The 1 in the carry flag can be rotated into the low
nibble of a register, ORed with 30H to give the ASCII code for 1, and then sent to
the terminal.
The AAA instruction works only on the AL register. The AAA instruction
updates AF and CF, but OF, PF, SF, and ZF are left undefined.

DAAǦDecimalAdjustALafterBCDAddition
This instruction is used to make sure the result of adding two packed BCD
numbers is adjusted to be a legal BCD number. The result of the addition must
be in AL for DAA to work correctly. If the lower nibble in AL after an addition is
greater than 9 or AF was set by the addition, then the DAA instruction will add 6
to the lower nibble in AL. If the result in the upper nibble of AL is now greater
than 9 or if the carry flag was set by the addition or correction, then the DAA
instruction will add 60H to AL.
EXAMPLES:
AL = 0101 1001 = 59 BCD ; BL = 0011 0101 = 35 BCD
ADD AL, BL AL = 1000 1110 = 8EH
DAA Add 01 10 because 1110 > 9 AL = 1001 0100 = 94 BCD
AL = 1000 1000 = 88 BCD BL = 0100 1001 = 49 BCD
ADD AL, BL AL = 1101 0001, AF=1
DAA Add 0110 because AF =1, AL = 11101 0111 = D7H
1101 > 9 so add 0110 0000
AL = 0011 0111= 37 BCD, CF =1
The DAA instruction updates AF, CF, PF, and ZF. OF is undefined after a DAA
instruction.

2.3.3.2 Subtraction Instructions

16
Chapter 2 Assembly Language Programming

SBB-Subtract with Borrow-SBB Destination, Source


SUB-Subtract-SUB Destination, Source
These instructions subtract the number in the indicated source from the number
in the indicated destination and put the result in the indicated destination. For
subtraction, the carry flag (CF) functions as a borrow flag. The carry flag will be
set after a subtraction if the number in the specified source is larger than the
number in the specified destination. In other words, the carry/borrow flag will
be set if a borrow was required to do the subtraction.
The Subtract instruction, SUB, subtracts just the contents of the specified
source from the contents of the specified destination. The Subtract with Borrow
instruction, SBB, subtracts the contents of the source and the contents of CF from
the contents of the indicated destination. The source may be an immediate
number, a register, or a memory location specified by any of the 24 addressing
modes. The destination can also be a register or a memory location. However, the
source and the destination cannot both be memory locations in an instruction.
The source and the destination must both be of type byte or both be of type
word. If we want to subtract a byte from a word, we must first move the byte to a
word location such as a 16-bit register and fill the upper byte of the word with
0's. AF, CF, OF, PF, SF, and ZF are updated by the SUB instruction.
EXAMPLES:
SUB CX, BX CX - BX. Result in CX
SBB CH, AL Subtract contents of AL and contents of CF from
contents of CH. Result In CH
SUB AX,3427H Subtract immediate number 3427H from AX
SBB BX,[3427H] Subtract word at displacement 3427H in DS and
contents of CF from BX
SUB PRICES[BX], 04H Subtract 04 from byte at effective address PRICES
[BX] if PRICES declared with DB. Subtract 04 from
word at effective address PRICES [BX] if PRICES
declared with DW.
SBB CX, TABLE[BX] Subtract word from effective address TABLE [BX]
and status of CF from CX.
SBB TABLE[BX], CX Subtract CX and status of CF from word in
memory at effective address TABLE[BX].
Example subtracting unsigned numbers
CL = 10011100 = 156 decimal BH = 00110111= 55 decimal
SUB CL, BH Result: CF,AF,SF,ZF = 0, OF,PF=1,CL=01100101= 101 decimal

šƒ ’Ž‡1•—„–”ƒ –‹‰•‹‰‡†— „‡”•


CL=00101110 = + 46 decimal BH= 01001010=+ 74 decimal
SUB CL, BH Results: AF,ZF = 0, PF = 1
CL = 11100100 = - 28 decimal CF = 1, borrow required
SF = 1, result negative

17
Chapter 2 Assembly Language Programming

OF = 0, magnitude of result fits in 7 bits


Example 2 subtracting signed numbers
CL= 10100001 = - 95 decimal BH= 01001100 = + 76 decimal
SUB CL,BH Results: CF,ZF = 0, AF,PF = 1 ,CL = 01010101 = + 85 decimal
SF = 0, result positive! OF = 1, invalid result.
The overflow flag being set indicates that the magnitude of the expected
result, - 171 decimal, is too large to fit in the 7 bits used for the magnitude in an
8-bit signed number. If the Interrupt on Overflow instruction, INTO, has been
executed previously, this error will cause the 8086 to perform a software
interrupt procedure. Part of this procedure is a user-written subroutine to handle
the error.

DECǦDecrementDestinationRegisterorMemoryǦDECDestination
This Instruction subtracts 1 from the destination word or byte. The
destination can be a register or a memory location specified by any one of the 24
addressing modes. AF, OF, PF, SF, and ZF are updated, but CF is not affected.
This means that if an 8-bit destination containing 00H or a 16-bit destination
containing 0000H is decremented, the result will be FFH or FFFFH with no carry
(borrow).

 
DEC CL Subtract 1 from contents of CL register
DEC BP Subtract 1 from contents of BP register
DEC BYTE PTR [BX] Subtract 1 from byte at offset [BX]in DS. The BYTE PTR
directive is necessary to tell the assembler to put in the correct code for
decrementing a byte in memory, rather than decrementing a word. The
instruction essentially says, "Decrement the byte in memory pointed to by the
offset in BX. "
DEC WORD PTR [BP] Subtract 1 from a word at offset [BP] in SS. The WORD
PTR directive tells the assembler to put in the code for decrementing a word
pointed to by the contents of BP. An offset in BP will be added to the SS register
contents to produce the physical address.
DEC TOMATO_CAN_COUNT, Subtract 1 from byte or word named
TOMATO_CAN_COUNT in DS. If TOMATO_CAN_COUNT was declared with
a DB, then the assembler will code this instruction to decrement a byte. If
TOMATO-CAN-COUNT was declared with a DW, then the assembler will code
this instruction to decrement a word.

NEGǦForm2'sComplementǦNEGDestination
This Instruction replaces the number in a destination with the 2's
complement of that number. The destination can be a register or a memory
location specified by any one of the 24-addressing modes. This instruction forms

18
Chapter 2 Assembly Language Programming

the 2's complement by subtracting the original word or byte in the indicated
destination from zero. As shown in some of the following examples, the NEG
Instruction is useful for changing the sign of a signed word or byte. An attempt
to NEG a byte location containing - 128 or a word location containing - 32,768
will produce no change in the destination contents because the maximum
positive signed number in 8 bits is + 127 and the maximum positive signed
number In 16 bits is + 32,767. OF will be set to Indicate that the operation could
not be done. The NEG instruction updates AF, CF, SF, PF, ZF, and OF.
EXAMPLES:
NEG AL Replace number in AL with its 2's complement
NEG BX Replace word in BX with its 2's complement
NEG BYTE PTR [BX] Replace byte at offset [BX] in DS with its 2's
complement
NEG WORD PTR [BP] Replace word at offset [BP] in SS with its 2's
complement

CMPǦCompareByteorWordǦCMPDestination,Source
This instruction compares a byte from the specified source with a byte
from the specified destination, or a word from the specified source with a word
from the specified destination. The source can be an immediate number, a
register, or a memory location specified by one of the 24 addressing modes. The
destination can be a register or a memory location. However, the source and the
destination cannot both be memory locations in the same instruction. The
comparison is actually done by subtracting the source byte or word from the
destination byte or word. The source and the destination are not changed, but
the flags are set to indicate the results of the comparison. AF, OF, SF, ZF, PF, and
CF are updated by the CMP instruction. For the instruction CMP CX, BX
CF, ZF, and SF will be left as follows:
CF ZF SF
CX = BX 0 1 0 Result of subtraction is 0
CX > BX 0 0 0 No borrow required, so CF = 0
CX < BX 1 0 1 Subtraction required borrow, so CF = 1
EXAMPLES:
CMP AL, 01H Compare immediate number01H with byte In AL
CMP BH, CL Compare byte in CL with byte in BH
CMP CX, TEMP_MIN Compare word in DS at displacement TEMP_MIN
with word in CX
CMP TEMP-MAX, CX Compare CX with word in DS at displacement TEMP-
MAX
CMP PRICES [BX], 49H Compare immediate 49H with byte at offset [BX] in
array PRICES

19
Chapter 2 Assembly Language Programming

NOTE: The Compare instructions are often used with the Conditional Jump
instructions. Having the Compare instructions formatted the way they are makes this use
very easy to understand.

AASǦǦASCIIAdjustforSubtraction
Numerical data coming into a computer from a terminal is usually in
ASCII code. In this code the numbers 0 to 9 are represented by the ASCII codes
30H to 39H. The 8086 allows us to subtract the ASCII codes for two decimal
digits without masking the "3" in the upper nibble of each. The AAS instruction
is then used to make sure the result is the correct unpacked BCD. Some simple
numerical examples will show how this works.
EXAMPLE:
ASCII 9-ASCII 5 (9-5)
AL = 00111001 = 39H = ASCII 9
BL = 001 10101 = 35H = ASCII 5
SUB AL, BL Result: AL = 00000100 = BCD 04 and CF = 0
AAS Result: AL = 00000100 = BCD 04 and CF = 0
no borrow required
ASCII 5-ASCII 9 (5-9)
Assume AL = 00110101 = 35H ASCII 5
and BL = 0011 1001 = 39H = ASCII 9
SUB AL, BL Result: AL = 11111100 = - 4 in 2s complement and CF =1
AAS Result: AL = 00000100 = BCD 04 and CF = 1, borrow needed
The AAS instruction leaves the correct unpacked BCD result in the low
nibble of AL and resets the upper nibble of AIL to all 0's. If we want to send the
result back to a CRT terminal, we can OR AL with 30H to produce the correct
ASCII code for the result. If multiple-digit numbers are being subtracted, the CF
can be taken into account by using the SBB instruction when subtracting the next
digits.
The AAS instruction works only on the AL register. It updates AF and CF, but
OF, PF, SF, and ZF are left undefined.

DASǦDecimalAdjustafterBCDSubtraction
This instruction is used after subtracting two packed BCD numbers to
make sure the result is correct packed BCD. The result of the subtraction must be
in AL for DAS to work correctly. If the lower nibble in AL after a subtraction is
greater than 9 or the AF was set by the subtraction, then the DAS instruction will
subtract 6 from the lower nibble of AL. If the result in the upper nibble is now
greater than 9 or if the carry flag was set, the DAS instruction will subtract 60
from AL.
EXAMPLES:
AL 1000 0110 86 BCD ; BH 0101 0111 57 BCD

20
Chapter 2 Assembly Language Programming

SUB AL,BH AL 0010 1111 2FH, CF = 0


DAS Lower nibble of result is 1111, so DAS automatically
subtracts 0000 0110 to give AL = 00101001 29 BCD
AL 0100 1001 49 BCD BH 0111 0010 72 BCD
SUB AL,BH AL 1101 0111 D7H, CF = 1
DAS Subtracts 0110 0000 (- 60H) because 1101 in upper nibble > 9
AL = 01110111= 77 BCD, CF=1 CF=1 means borrow was
needed
The DAS instruction updates AF, CF, SF, PF, and ZF, but OF is undefined.

2.3.3.3. Multiplication Instructions


MULǦǦǦMultiplyUnsignedBytesorWordsǦǦǦMULSource
This instruction multiplies an unsigned byte from some source times an
unsigned byte in the AL register or an unsigned word from some source times an
unsigned word In the AX register. The source can be a register or a memory
location specified by any one of the 24 addressing modes. When a byte is
multiplied by the contents of AL, the result (product) is put in AX. A 16-bit
destination is required because the result of multiplying an 8-bit number by an 8-
bit number can be as large as 16 bits. The most significant byte of the result is put
in AH, and the least significant byte of the result is put in AL. When a word is
multiplied by the contents of AX, the product can be as large as 32 bits. The most
significant word of the result is put in the DX register, and the least significant
word of the result is put in the AX register. If the most significant byte of a 16-bit
result or the most significant word of a 32-bit result is 0, CF and OF will both be
0's. Checking these flags, then, allows us to detect and perhaps discard
unnecessary leading 0's in a result. AF, PF, SF, and ZF are undefined after a MUL
Instruction.
If we want to multiply a byte by a word, we must first move the byte to a
word location such as an extended register and fill the upper byte of the word
with all 0's.
EXAMPLES:
MUL BH AL times BH, result in AX
MUL CX AX times CX, result high word in DX, low word in AX
MUL BYTE PTR [BX] AL times byte in DS pointed to by IBXI
MUL CONVERSION_FACTOIR[BX] Multiply AL times byte at effective
address CONVERSION-FACTORIBXI if it was declared as type byte with DB.
Multiply AX times word at effective address CONVERSION_FACTOR [BX] if it
was declared as type word with DW.
; Example showing a byte multiplied by a word
MOV AX, MULTIPLICAND_16 Load 16-bit multiplicand into AX
MOV CL, MULTIPLIER_8 Load 8-bit multiplier into CL

21
Chapter 2 Assembly Language Programming

MOV CH, 00H Set upper byte of CX to all 0's


MUL CX AX times CX, 32-bit result in DX and AX

IMUL-Multiply Signed Numbers--IMUL Source


This instruction multiplies a signed byte from some source times a signed
byte in AL or a signed word from some source times a signed word in AX. The
source can be another register or a memory location specified by any one of the
24 addressing modes shown. When AL multiplies a byte from some source, the
signed result (product) will be put in AX. A 16-bit destination is required because
the result of multiplying two 8-bit numbers can be as large as 16 bits. When a
word from some source is multiplied by AX, the result can be as large as 32 bits.
The high-order (most significant) word of the signed result is put in DX, and the
low-order (least significant) word of the signed result is put in AX. If the
magnitude of the product does not require all the bits of the destination, the,
unused bits will be filled with copies of the sign bit. If the upper byte of a 16-bit
result or the upper word of a 32-bit result contains only copies of the sign bit (all
0's or all 1's), then CF and the OF will both be 0. If the upper byte of a 16-bit
result or the upper word of a 32-bit result contains part of the product, CF and
OF will both be 1. We can use the status of these flags to determine whether the
upper byte or word of the product needs to be kept. AF, PF, SF, and ZF are
undefined after IMUL.
If we want to multiply a signed byte by a signed word, we must first
move the byte into a word location and fill the upper byte of the word with
copies of the sign bit. If we move the byte into AL, we can use the 8086 Convert
Byte to Word instruction, CBW, to do this. CBW extends the sign bit from AL
into all the bits of AH. Once we have converted the byte to, a word, we can do
word times word IMUL. The result of this multiplication will be in DX and AX.
EXAMPLES:
IMUL BH Signed byte in AL times signed byte in BH, result in AX
IMUL AX AX times AX, result in DX and AX

Multiplyingasignedbytebyasignedword
MOV CX, MULTIPLIER Load signed word in CX
MOV AL, MULTIPLICAND Load signed byte in AL
CBW Extend sign of AL into AH
IMUL CX Result in DX and AX

69 x 14
AL = 01000101 = 69 decimal, BL = 00001110 = 14 decimal
IMUL BL AX = 03C6H = + 966 decimal
MSB = 0, positive result magnitude in true form.
SF = 0, CF,OF = 1

22
Chapter 2 Assembly Language Programming

-28 x 59 AL = 11100100 = - 28 decimal BL = 00111011 = + 59


decimal
IMUL BL AX = F98CH = - 1652 decimal MSB = 1, negative result
magnitude in 2's complement. SF, CF, OF = 1

AAMǦBCDAdjustafterMultiply
Before we can multiply two ASCII digits, we must first mask the upper 4
bits of each. This leaves unpacked BCD (one BCD digit per byte) in each byte.
After the two unpacked BCD digits are multiplied, the AAM instruction is used
to adjust the product to two unpacked BCD digits In AX.
AAM works only after the multiplication of two un- packed BCD bytes,
and it works only on an operand in AL. AAM updates PF, SF, and ZF, but AF,
CF, and OF are left undefined.
EXAMPLE:
AL 00000101 unpacked BCD 5
BH 00001001 unpacked BCD 9
MUL BH AL x BH; result in AX
AX = 00000000 00101101 = 002DH
AAM AX = 00000100 00000101 = 0405H,
which is unpacked BCD for 45.
If ASCII codes for the result are desired, use next instruction
OR AX, 3030H Put 3 in upper nibble of each byte.
AX = 0011 0100 0011 0101 = 3435H, which is ASCII code for 45

2.3.3.4. Division Instructions

DIV-Unsigned Divide-DIV Source


This instruction is used to divide an unsigned word by a byte or to divide
an unsigned doubleword (32 bits) by a word.
When a word is divided by a byte, the word must be in the AX register.
The divisor can be in a register or a memory location. After the division, AL will
contain an 8-bit result (quotient), and AH will contain an 8-bit remainder. If an
attempt is made to divide by 0 or if the quotient is too large to fit in AL (greater
than FFH), the 8086 will automatically do a type 0 interrupt.
When a doubleword is divided by a word, the most significant word of
the doubleword must be in DX, and the least significant word of the doubleword
must be in AX. After the division, AX will contain the 16-bit result (quotient),
and DX will contain a 16-bit remainder. Again, if an attempt is made to divide by
0 or if the quotient Is too large to fit in AX (greater than FFFFH), the 8086 will do
a type 0 interrupt.
For a DIV, the dividend (numerator) must always be in AX or DX and AX,
but the source of the divisor (denominator) can be a register or a memory

23
Chapter 2 Assembly Language Programming

location specified by any one of the 24 addressing modes. If the divisor does not
divide an integral number of times into the dividend the quotient is truncated,
not rounded. The example below will illustrate this. All flags are undefined after
a DIV instruction.
If we want to divide a byte by a byte, we must first put the dividend byte
In AL and fill AH with all 0's. The SUB AH, AH instruction is a quick way to do
this. Likewise, if we want to divide a word by a word, put the dividend word in
AX and fill DX with all 0's. The SUB DX, DX instruction does this quickly.
EXAMPLES:
DIV BL Divide word in AX by byte in BL. Quotient in AL, remainder in AH
DIV CX Divide doubleword in DX and AX by word in CX.
Quotient in AX, remainder in DX.
DIV SCALE [BX] AX/(byte at effective address SCALE[BX]), if SCALE[BX] is of
type byte or (DX and AX)/(word at effective address SCALE
[BX]) if SCALE[BX] is of type word
DIV BH AX = 37D7H = 14,295 decimal BH = 97H = 151 decimal
AX/BH, AL = quotient = 5EH = 94 decimal
AH = remainder = 65H = 101 decimal
Since the remainder is greater than half of the divisor, the actual quotient is
closer to 5FH than to the 5EH produced. However, as indicated before, the
quotient is always truncated to the next lower integer rather than rounded to the
closest integer. If we want to round the quotient, we can compare the remainder
with (divisor/2) and add 1 to the quotient if the remainder is greater than
(divtsor/2).

IDIVǦDividebySignedByteorWordǦIDIVSource
This instruction is used to divide a signed word by a signed byte, or to
divide a signed doubleword (32 bits) by a signed word.
When dividing a signed word by a signed byte, the word must be in the
AX register. The divisor can be in an 8-bit register or a memory location. After
the division, AL will contain the signed result (quotient), and AH will contain the
signed remainder. The sign of the remainder will be the same as the sign of the
dividend. If an attempt is made to divide by 0, the quotient is greater than 127
(7FH), or the quotient is less than -127 (81 H), the 8086 will automatically do a
type 0 Interrupt. For the 80186, 80286, etc. this range is - 128 to + 127.
When dividing a signed doubleword by a signed word, the most
significant word of the dividend (numerator) must be in the DX register, and the
least significant word of the dividend must be in the AX register. The divisor can
be in any other 16-bit register or memory location. After the division, AX will
contain a signed 16-bit quotient, and DX will contain a signed 16-bit remainder.
The sign of the remainder will be the same as the sign of the dividend. Again, if
an attempt is made to divide by 0, the quotient is greater than +32,767 (7FFFH),

24
Chapter 2 Assembly Language Programming

or the quotient is less than - 32,767 (800 1 H), the 8086 will automatically do a
type 0 interrupt. For the 80186, 80286, etc., this range is - 32,768 to + 32,767.
If the divisor does not divide evenly into the dividend, the quotient will
be truncated, not rounded. An example, below illustrates this. All flags are
undefined after an IDIV.
If we want to divide a signed byte by a signed byte, we must first put the
dividend byte in AL and fill AH with copies of the sign bit from AL. In other
words, if AL is positive (sign bit = 0), then AH should be filled with 0's. If AL is
negative (sign bit = 1), then AH should be filled with 1's. The 8086 Convert Byte
to Word instruction, CBW, does this by copying the sign bit of AL to all the bits
of AH. AH is then said to contain the “sign extension of AL." Likewise, if we
want to divide a signed word by a signed word, we must put the dividend word
in AX and extend the sign of AX to all the bits of DX. The 8086 Convert Word to
Doubleword instruction, CWD, will copy the sign bit of AX to all the bits of DX.
EXAMPLES:
IDIV BL Signed word in AX/signed byte in BL
IDIV BP Signed doubleword in. DX and AX/signed word in BP
IDIV BYTE PTR [BX] AX/byte at offset [BX] in DS
MOV AL, DIVIDEND Position byte dividend
CBW Extend sign of AL into AH
IDIV DMSOR Divide by byte divisor

EXAMPLES

Asignedworddividedbyasignedbyte
AX = 00000011 10101011 03ABH = 39 decimal
BL 11010011 = D3H = - 2DH = - 45 decimal
IDIV BL Quotient: AL = ECH = -14H = -20 decimal
Remainder: AH = 27H + 39 decimal
NOTE: The quotient is negative because positive was divided -by negative. The
remainder has same sign as dividend (positive).
•‹‰‡†„›–‡†‹˜‹†‡†„›ƒ•‹‰‡†„›–‡
AL 1101 1010 - 26 H = - 38 decimal
CH 0000 0011 + 3H = + 3 decimal
CBW Extend sign of AL through AH,
AX= 11111111 11011010
IDIV CH Divide AX by CH
AL 11110100 = -0CH = -12 decimal
AH 11111110 = 2H = -2 decimal
Although the quotient is actually closer to 13 (12.666667) than to 12, the 8086
truncate it to 12 rather than rounding it to 13. If we want to round the quotient,
we can compare the magnitude of the remainder with (divisor/2) and add 1 to

25
Chapter 2 Assembly Language Programming

the quotient if the remainder is greater than (divisor/2). Note that the sign of the
remainder is the same as the sign of the dividend (negative). All flags are
undefined after IDIV.

AAD -BCD-to-Binary Convert before Division


AAD converts two unpacked BCD digits in AH and AL to the equivalent
binary number in AL. This adjustment must be made before dividing the two
unpacked BCD digits in AX by an unpacked BCD byte. After the division, AL
will contain the unpacked BCD quotient and AH will contain the unpacked BCD
remainder. PF, SF, and ZF are updated. AF, CF, and OF are undefined after
AAD.
EXAMPLE:
AX = 0607H unpacked BCD for 67 decimal CH = 09H, now
adjust to binary
AAD Result: AX = 0043 = 43H = 67 decimal
DIV CH Divide AX by unpacked BCD in CH
Quotient: AL = 07 unpacked BCD Remainder:
AH = 04 unpacked BCD Flags undefined after DIV
NOTE: If an attempt is made to divide by 0, the 8086 will do a type 0 interrupt.

CBW-Convert Signed Byte to Signed Word


This instruction copies the sign of a byte in AL to all the bits in AH. AH is
then said to be the sign extension of AL. The CBW operation must be done before
a signed byte in AL can be divided by another signed byte with the IDIV
instruction. CBW affects no flags.
EXAMPLE:
AX = 00000000 10011011 155 decimal
CBW Convert signed byte in AL to signed word in AX
Result: AX = 11111111 10011011 155 decimal
For further examples of the use of CBW, see the IDIV instruction description.

CWD-Convert Signed Word to Signed Double word


CWD copies the sign bit of a word in AX to all the bits of the DX register.
In other words it extends the sign of AX into all of DX. The CWD operation must
be done before a signed word in AX can be divided by another signed word with
the IDIV instruction. CWD affects no flags.
EXAMPLE:
DX = 00000000 00000000
AX = 11110000 11000111 3897 decimal
CWD Convert signed word in AX to signed doubleword in DX:AX
Result DX = 11111111 11111111
AX = 11110000 11000111 3897 decimal

26
Chapter 2 Assembly Language Programming

2.3.4. Bit Manipulation Instructions


2.3.4.1 Logical Instructions

NOTǦInvertEachBitofOperandǦNOTDestination
The NOT instruction inverts each bit (forms the I's complement) of the
byte or word at the specified destination. The destination can be a register or a
memory location specified by any one of the 24 addressing modes. No flags are
affected by the NOT Instruction.
EXAMPLES:
NOT BX Complement contents of BX register
NOT BYTE PTR [BX] Complement memory byte at offset IBXI in data segment

ANDǦANDCorrespondingBitsofTwoOperandsǦǦANDDestination,Source
This instruction ANDs each bit in a source byte or word with the same
number bit in a destination byte or word. The result is put in the specified
destination. The contents of the specified source will not be changed. The result
for each bit position will follow the truth table for a two-input AND gate. In
other words, a bit in the specified destination will be a 1 only if that bit is a 1 in
both the source and the destination operands. Therefore, a bit can be masked
(reset) by ANDing it with 0.
The source operand can be an immediate number, the contents of a
register, or the contents of a memory location specified by one of the 24
addressing modes. The destination can be a register or a memory location. The
source and the destination cannot both be memory locations in the same
instruction. CF and OF are both 0 after AND. PF, SF, and ZF are updated by
AND. AF is undefined. Note that PF has meaning only for an 8-bit operand.
EXAMPLES :
AND CX, [SI] AND word in DS at offset [SI] with word in CX register
Result in CX register
AND BH, CL AND byte in CL with byte in BH Result in BH
AND BX, 00FFH AND word in BX with immediate 00FFH.
Masks upper byte, leaves lower byte unchanged

BX = 10110011 01011110
AND BX, 00FFH Mask out upper 8 bits of BX
Result: BX = 00000000 01011110 CF, OF, PF, SF, ZF = 0

OR-Logically OR Corresponding Bits of Two Operands-OR Destination,


Source
This instruction ORs each bit in a source byte or word with the
corresponding bit in a destination byte or word. The result is put in the specified

27
Chapter 2 Assembly Language Programming

destination. The contents of the specified source will not be changed. The result
for each bit will follow the truth table for a two-input OR gate. In other words, a
bit in the destination will become a 1 if that bit is a 1 in the source operand or
that bit is a1in the original destination operand. Therefore. a bit in the destination
operand can be set to a 1 by simply ORing that bit with a 1 in the same bit of the
source operand.
The source operand can be an immediate number, the contents of a
register, or the contents of a memory location specified by one of the 24
addressing modes. The destination can be a register or a memory location. The
source and the destination cannot both be memory locations in the same
instruction. CF and OF are both 0 after OR. PF, SF, and ZF are updated by the OR
instruction. AF is undefined after OR. Note that PF has meaning only for the
lower 8 bits of a result.
EXAMPLES (SYNTAX):
OR AH, CL CL ORed with AH, result in AH. CL not changed
OR BP, SI SI ORed with BP, result in BP. SI not changed
OR SI, BP BP ORed with SI, result in SI. BP not changed
OR BL, 80H BL ORed with immediate 80H. Set MSB of BL to a 1
OR CX, TABLE [BX][SI] CX ORed with word from effective address
TABLE[BX][SI] in data segment.
OR CX, 0FF00H CX = 00111101 10100101 ,OR CX with immediate
FF00H, Result in CX = 11111111 10100101
CF=0,OF=0,PF= 1,SF= 1,ZF=0.

XOR-Exclusive OR Corresponding Bits of Two Operands


XOR Destination, Source
This instruction Exclusive-ORs each bit in a source byte or word with the
same number bit in a destination byte or word. The result replaces the contents
of the specified destination. The contents of the specified source will not be
changed. The result for each bit position will follow the truth table for a two-
input Exclusive OR gate. In other words, a bit in the destination will be set to a 1
if that bit in the source and that bit in the original destination were not the same.
A bit Exclusive-ORed with a 1 will be inverted. A bit Exclusive-ORed with a 0
will not be changed. Because of this, we can use the XOR instruction to
selectively invert or not invert bits in an operand.
The source operand can be an immediate number, the contents of a
register, or the contents of a memory location specified by any one of the
addressing mode. The destination can b a register or a memory location. The
source and destination cannot both be memory locations in the same instruction.
CF and OF are both 0 after XOR. PF, SF, and ZF are updated. PF has meaning
only for an 8-bit operand. AF is undefined after XOR.
EXAMPLES:

28
Chapter 2 Assembly Language Programming

XOR CL,BH Byte in BH Exclusive-ORed with byte in CL. Result in CL.


BH not chanced
XOR BP,DL Word in DI Exclusive-ORed with word in BP. Result in BP.
DI not changed
XOR WORD PTR [BX], 00FFH
Exclusive-OR immediate number OOFFH with word at offset [BXI in data
segment. Result in memory location [BX]
BX = 0011110 01101001 , CX = 00000000 11111111
XOR BX,CX Result: BX = 0011110110010110 Note bits in lower byte are
inverted CF,OF,SF,ZF = 0, PF = 1, AF

TESTǦANDOperandstoUpdateFlagsǦTESTDestination,Source
This instruction ANDs the contents of a source byte or word with the
contents of the specified destination word. Flags are updated, but neither
operand is changed. The TEST instruction is often used to set flags before a
Conditional Jump instruction.
The source operand can be an immediate number, the contents of a
register, or the contents of a memory location specified by one of the 24
addressing modes. The destination operand can be in a register or in a memory
location. The source and the destination cannot both be memory locations in an
instruction. CF and OF are both 0's after TEST. PF, SF, and ZF will be updated to
show the results of the ANDing. PF has meaning only for the lower 8 bits of the
destination. AF will be undefined.
EXAMPLES:
TEST AL, BH AND BH with AL, no result stored. Update PF, SF, ZF
TEST CX, 0001 H AND CX with immediate number 0001H, no result
stored. Update PF, SF, ZF
TEST BP, [BX][DI] AND word at offset [BX][DI] in DS with word in BP.
no result stored. Update PF, SF, and ZF

šƒ ’Ž‡‘ˆƒ’‘ŽŽ‹‰•‡“—‡ ‡—•‹‰


AGAIN: IN AL, 2AH Read port with strobe connected to LSB
TEST AL, 01H AND immediate 01 H with AL to test if LBB of
AL is 1 or 0 ZF = 1 if LSB of result is 0 No
result stored
JZ AGAIN Read port again if LSB = 0
AL = 01010001
TEST AL, 80H AND immediate 80H with AL to test if MSB of AL is 1 or 0
ZF = 1if MSB of AL = 0. AL = 01010001 (unchanged)
PF = 0, SF = 0, ZF = 1, because ANDing produced 00.

2.3.4.2 Shift Instructions


SAL/SHL-Shift Operand Bits Left, Put Zero in LSB(s)-

29
Chapter 2 Assembly Language Programming

SAL/SHL Destination, Count


SAL and SHL are two mnemonics for the same instruction. This
instruction shifts each bit in the specified destination some number of bit
positions to the left. As a bit is shifted out of the LSB position, a 0 is put In the
LSB position. The MSB will be shifted into CF. In the case of multiple bit shifts,
CF will contain the bit most recently shifted in from the MSB. Bits shifted into CF
previously will be lost. See the following diagram.
CF MSB LSB 0
The destination operand can be a byte or a word. It can be in a register or
in a memory location specified by any one of the 24 addressing modes.
If the desired number of shifts is one, this can be specified by putting a 1
in the count position of the instruction. For shifts of more than 1 bit position, the
desired number of shifts is loaded into the CL register, and CL is put in the count
position of the instruction. The advantage of using the CL register is that the
number of shifts can be dynamically calculated as the program executes.
The flags are affected as follows: CF contains the bit most recently shifted
in from MSB. For a count of one, OF will be 1 if CF and the current MSB are not
the same. For multiple-bit shifts, OF is undefined. SF and ZF will be updated to
reflect the condition of the destination. PF will have meaning only for an operand
in AL. AF is undefined.
EXAMPLES:
SAL BX, 1 Shift word in BX1bit position left, 0 in LSB
MOV CL, 02H Load desired number of shifts in CL
SAL BP, CL Shift word in BP left (CL) bit positions, 0's in 2 LSBs

SAL BYRE PTR [BX], 1 Shift byte In DS at offset [BX],


1 bit position left, 0 in LSB
IN AL, COUNTER_DIGIT
MOV CL, 04H Set count for 4 bit positions
SAL AL, CL Shift BCD to upper nibble, 0's in lower nibble.
Ready to OR another BCD digit into lower nibble of AL

SHRǦShiftOperandBitsRight,PutZeroinMSB(s)ǦSHRDestination,Count
This instruction shifts each bit in the specified destination some number of
bit positions to the right. As a bit is shifted right out of the MSB position, a 0 is
put in its place. The bit shifted out of the LSB position goes to CF. In the case of a
multiple-bit shift, CF will contain the bit most recently shifted in from the LSB.
Bits shifted into CF previously will be lost. See the following diagram.
0 MSB LSB CF
The destination operand can be a byte or a word in a register or in a
memory location specified by any one of the 24 addressing modes.

30
Chapter 2 Assembly Language Programming

If the desired number of shifts is one, this can be specified by putting a 1


in the count position of the instruction. For shifts of more than one bit position,
the desired number of shifts is loaded into the CL register, and CL is put in the
count position of the instruction.
The flags are affected by SHR as follows: CF contains the bit most recently
shifted in from the LSB. For a 'count of one, OF will be a 1 if the two MSBs are
not both O's. For multiple-bit shifts, OF is meaningless. SF and ZF will be
updated to show the condition of the destination. PF will have meaning only for
the lower 8 bits of the destination. AF is undefined.
SHR BP, 1 Shift word in BP one bit position right, 0 in MSB
MOV CL,03H Load desired number of shifts into CL
SHR BYTE PM IBXI Shift byte in DS at offset [BX] 3 bits right.
0's in 3 MSBs
Example of SHR used to help unpack two BCD digits in AL to BH and BL
MOV BLAL Copy packed BCD to BL
AND BL,0FH Mask out upper nibble. Low BCD digit now in BL
MOV CL,04H Load count for shift in CL
SHR AL,CL Shift AL four bit positions right and put 0's in upper 4 bits
MOV BH.AL Copy upper BCD nibble to BH

SARǦShiftOperandBitsRight,NewMSBOldMSBǦSARDestination,Count
This instruction shifts each bit in the specified destination some number of
bit positions to the right. As a bit is shifted out of the MSB position, a copy of the
old MSB is put in the MSB position. In other words, the sign bit is copied into the
MSB. The LSB will be shifted into CF. In the case of multiple bit shifts; CF will
contain the bit most recently shifted in from the LSB. Bits shifted into CF
previously will be lost. See the following diagram.
MSB MSB LSB CF
The destination operand can be a byte or a word. It can be in a register or
in a memory location specified by any one of the 24 addressing modes.
If the desired number of shifts is one, this can be specified by putting a 1
in the count position of the instruction. For shifts of more than one bit position,
the desired number of shifts is loaded into the CL register, and CL is put in the
count position of the instruction.
The flags are affected as follows: CF contains the bit most recently shifted in from
the LSB. For a count of one, OF will be a 1 if the two MSBs are not the same. After
a multibit SAR, OF will be 0. SF and ZF will be updated to show the condition of
the destination. PF will have meaning only for an 8-bit destination. AF will be
undefined after SAR.
EXAMPLES:
SAR DI, 1 Shift word in DI one bit position right, new MSB = old MSB
MOV CL, 02H Load desired number of shifts in CL

31
Chapter 2 Assembly Language Programming

SAR WORD PTR [BP], CL Shift word at offset [BP] in stack segment right
two bit positions. Two MSBs are now copies of
original MSB
2.3.4.3. Rotate Instructions
ROLǦRotateAllBitsofOperandLeft,MSBtoLSBǦROLDestination,Count
This instruction rotates all the bits in a specified word or byte to the left
some number of bit positions. The operation can be thought of as circular,
because the data bit rotated out of the MSB is circled back into the LSB. The data
bit rotated out of the MSB is also copied to CF during ROL. In the case of
multiple bit rotates, CF will contain a copy of the bit most recently moved out of
the MSB. See the following diagram.

CF MSB LSB

The destination operand can be in a register or in a memory location


specified by any one of the 24 addressing modes. If we want to rotate the
operand one bit position, we can specify this by putting a 1 in the count position
of the instruction. To rotate more than one bit position, load the desired number
in the CL register and put "CL" In the count position of the Instruction.
ROL affects only CF and OF. After ROL, CF will contain the bit most
recently rotated out of the MSB. OF will be a1after a single bit ROL if the MSB
was changed by the rotate.
The ROL instruction can be used to swap the nibbles in a byte or to swap
the bytes in a word. It can also be used to rotate a bit into CF, where it can be
checked and acted upon by the Conditional Jump instructions JC (Jump if Carry)
and JNC (Jump if No Carry).
EXAMPLES:
ROL AX, 1 Word in AX1bit position left, MSB to LSB and CF
MOV CL, 04H Load number of bits to rotate in CL
ROL BL, CL Rotate BL 4 bit positions (swap nibbles)
ROL FACTOMBXI, 1 MSB of word or byte in DS at EA = FACTOR[BXI]
1 bit position left into CF
JC ERROR Jump if CF =1to en-or routine

ROL BH, 1 CF = 0, BH = 10101110 , Result: CF,OF = 1,


BH = 0101 1101
ROL BX,CL BX = 0101110011010011, CL = 8, set for 8-bit rotate
Rotate BX 8 times left (swap bytes)
CF = 0, BX = 1101001101011100, OF undefined

32
Chapter 2 Assembly Language Programming

RORǦRotateAllBitsofOperandRight,LSBtoMSBǦRORDestination,Count
This Instruction rotates all the bits of the specified word or byte some
number of bit positions to the right. The operation is described as a rotate rather
than a shift because the bit moved out of the LSB is rotated around into the MSB.
To help visualize the operation, think of the operand as a loop with the LSB
connected around to the MSB. The data bit moved out of the LSB is also copied to
CF during ROR. See the following diagram. In the case of multiple-bit rotates, CF
will contain a copy of the bit most recently moved out of the LSB.

MSB LSB CF

The destination operand can be in a register or in a memory location


specified by any one of the 24 ad- dressing modes. If we want to rotate the
operand one bit position, we can specify this by putting a 1 in the count position
of the instruction. To rotate more than one bit position, load the desired number
in the CL register and put "CL" in the count position of the instruction.
ROR affects only CF and OF. After ROR, CF will contain the bit most
recently rotated out of the LSB. For a single- bit rotate, OF will be 1 after ROR if
the MBB is changed by the rotate.

RCLǦRotateOperandAroundtotheLeftthroughCFǦRCLDestination,Count
This instruction rotates all the bits in a specified word or byte some
number of bit Positions to the left. The operation is circular because the MSB of
the operand is rotated into the carry flag and the bit in the carry flag is rotated
around into the LSB of the operand. See the following diagram.
CF

MSB LSB

The "C" In the middle of the mnemonic should help us remember that CF
is in the rotated loop and help distinguish this instruction from the ROL
instruction. For multi-bit rotates, CF will contain the bit most recently rotated out
of the MSB.
The destination operand can be in a register or in a memory location,
specified by any one of the 24 addressing modes. If we want to rotate the
operand one bit position, we can specify this by putting a 1 in the count position
of the instruction. To rotate more than one bit position, load the desired number
into the CL register and put "CL" in the count position of the Instruction.
RCL affects only CF and OF. After RCL, CF will contain the bit most
recently rotated out of the MSB. OF will be a 1 after a single-bit RCL if the MSB
was changed by the rotate. OF is undefined after a multi-bit rotate.
The RCL instruction is a handy way to move CF into the LSB of a register
or memory location to save it after addition or subtraction.

33
Chapter 2 Assembly Language Programming

EXAMPLES:
RCL DX, 1 Word in DX 1 bit left, MSB to CF, CF to LSB
MOV CL,4 Load number of bit positions to rotate into CL
RCL SUM [BX], CL Rotate byte or word at effective address SUM[BX], 4
bits left Original bit 4 now in CF, original CF now in
bit 3
RCL BH, 1 CF = 0, BH = 1011 0011 ,Result: BH= 0110 0110
CF = 1, OF =1 because MSB changed CF = 1,
AX= 0001 1111 1010 1001
MOV CL, 2 Load CL for rotating 2 bit positions
RCL AX, CL Result: CF = 0, OF undefined AX = 0111 1110 1010 0110

RCR-Rotate Operand Around to the Right through CF - RCR Destination,


Count
This instruction rotates all the bits in a specified word or byte some
number of bit positions to the right. The operation is circular because the LSB of
the operand is rotated into the carry flag and the bit in the carry flag is rotated,
around into the MSB of the operand. See the following diagram.

CF

MSB LSB

The "C" in the middle of the mnemonic should help us remember that CF
is in the rotated loop and should help distinguish this instruction from the ROR
instruction. For multi-bit rotates, CF will contain the bit most recently rotated out
of the LSB.
The destination operand can be in a register or in a memory location
specified by any one of the 24 addressing modes. If we want to rotate the
operand one bit position, we can specify this by putting a1in the count position
of the instruction. To rotate more than one bit position, load the desired number
into the CL register and put "CL" In the count position of the instruction.
RCR affects only CF and OF. After RCR, CF will contain the bit most
recently rotated out of the MSB. OF will be a1after a single-bit RCR if the MSB
was changed by the rotate. OF will be undefined after multibit rotates.
EXAMPLES:
RCR BX, 1 Word in BX right1bit CF to MSB, LSB to CF
MOV CL, 04H Load CL for rotating 4 bit positions
RCR BYTE PTR [BX] Rotate byte at offset [BX] in DS 4 bit positions right
CF = original bit 3. Bit 4 original CF

RCR BL, 1 CF = 1, BL = 001 1 1000

34
Chapter 2 Assembly Language Programming

Result: BL = 10011100, CF = 0 OF = 1 because MSB


changed to 1
CF = 0, WORD PTR [BX]= 0101111000001111
MOV CL, 02H Load CL for rotate 2 bit positions
RCR WORD PTR [BX], CL Rotate word in DS at offset [BX], 2 bits right
CF = original bit 1.
Bit 14 = original CF,WORD PTR [BX] = 10010111 10000011

2.3.5 String Instructions

MOVS/MOVSB/MOVSW -Move String Byte or String Word-MOVS Destination


String-Name, Source String-Name
This instruction copies a byte or a word from a location in the data
segment to a location in the extra segment. The offset of the source byte or word
in the data segment must be in the SI register. The offset of the destination in the
extra segment must be contained in the DI register. For multiple-byte or
multiple-word moves, the number of elements to be moved is put in the CX
register so that it can function as a counter. After the byte or word is moved, SI
and DI are automatically adjusted to point to the next source and the next
destination. If the direction flag is 0, then SI and DI will be incremented by 1 after
a byte move and incremented by 2 after a word move. If the DF is a 1, then SI
and DI will be decremented by 1 after a byte move and decremented by 2 after a
word move. MOVS affects no flags.
When using the MOVS instruction, we must in some way tell the
assembler whether we want to move a string as bytes or as words. There are two
ways to do this. The first way is to indicate the names of the source and
destination strings in the instruction, as, for example, MOVS STRING-DUMP,
STRING-CREATE. The assembler will code the instruction for a byte move if
STRING-DUMP and STRING-CREATE were declared with a DB. It will code the
instruction for a word move if they were declared with a DW. Note that this
reference to the source and destination strings does not load SI and DI. This must
be done with separate instructions. The second way to tell the assembler whether
to code the instruction for a byte or word move is to add a "B" or a "W" to the
MOVS mnemonic. MOVSB, for example, says move a string as bytes. MOVSW
says move a string as words.
EXAMPLE:
MOV SI, OFFSET SOURCE_STRING Load offset of start of source string in
DS into SI
MOV DI, OFFSET DESTINATION-STRING Load offset of start of destination
string in ES into DI

35
Chapter 2 Assembly Language Programming

CLD Clear direction flag to auto increment SI & DI after move


MOV CX, 04H Load length of string into CX as counter
REP MOVSB Decrement CX and copy string bytes until CX = 0
After the move, SI will be 1 greater than the offset of the last byte in the
source string. DI will be 1 greater than the offset of the last byte in the destination
string. CX will be 0.

LODS/LODSB/LODSWLoadStringByteintoALorLoadStringWordintoAX
This instruction copies a byte from a string location pointed to by SI to AL,
or a word from a string location pointed to by SI to AX. If the direction flag is
cleared (0), SI will automatically be incremented to point to the next element of
the string. For a string of bytes, SI will be incremented by 1. For a string of
words, SI will be incremented by 2 if the direction flag (DF) is set (1), SI will be
automatically decremented to point to the next string element. For a byte string,
SI will be decremented by 1, and for a word string, SI will be decremented by 2.
LODS affects no flags.
EXAMPLE:
CLD Clear direction flag so SI is auto incremented.
MOV SI, OFFSET SOURCE-STRING Point SI at start of string
LODS SOURCE-STRING Copy byte or word from string to AL or AX
NOTE: The assembler uses the name of the string to determine whether the
string is of type byte or type word. Instead of using the string name to do this,
we can use the mnemonic LODSB to tell the assembler that the string is of type
byte or the mnemonic LODSW to tell the assembler that the string is of type
word.

STOS/STOSB/STOSWǦStoreByteorWordinString
The STOS instruction copies a byte from AL or a word from AX to a
memory location in the extra segment pointed to by DI. In effect, it replaces a
string element with a byte from AL or a word from AX. After the copy, DI is
automatically incremented or decremented to point to the next string element in
memory. If the direction flag (DF) is cleared, then DI will automatically be
incremented by 1 for a byte string or incremented by 2 for a word string. If the
direction flag is set, DI will be automatically decremented by 1 for a byte string
or decremented by 2 for a word string. STOS does not affect any flags.
EXAMPLES:
Point DI at start of destination string
MOV DI, OFFGET TARGET_STRING
STOS TARGET_STRING Assembler uses string name to determine whether
string is of type byte or type word. If byte string, then string byte replaced with
contents of AL. If word string, then string word replaced with contents of AX
Point DI at start of destination string.
MOV DI,OFFSET TARGET_STRING

36
Chapter 2 Assembly Language Programming

STOSB "B" added to STOS mnemonic directly tells assembler


to replace byte in string with byte from AL. STOSW would tell assembler directly
to replace a word in the string with a word from AX.

SCAS/SCASB/SCASWǦScanaStringByteoraStringWord
SCAS compares a byte in AL or a word in AX with a byte or word pointed
to by DI in ES. Therefore, the string to be scanned must be in the extra segment,
and DI must contain the offset of the byte or the word to be compared. If the
direction flag is cleared (0), then DI will be incremented after SCAS. If the
direction flag is set (1), then DI will be decremented after SCAS. For byte strings,
DI will be incremented or decremented by 1, and for word strings, DI will be
incremented or decremented by 2. SCAS affects AF, CF, OF, PF, SF, and ZF, but it
does not change either the operand in AL (AX) or the operand in the string. This
instruction is often used with a repeat prefix to find the first occurrence of a
specified byte or word In a string.
EXAMPLE:
Scan a text string of 80 characters for a carriage return, ODH. Put offset of string
into DI.
MOV DI,OFFSET TEXT_STRING
MOV AL,ODH Byte to be scanned for into AL
MOV CX,80 CX used as element counter
CLD Clear DF so DI autoincrements
REPNE SCAS TEXT_STRING Compare byte in string with byte in AL
NOTE: Scanning is repeated as long as the bytes are not equal and the end of the
string has not been reached. If a carriage return ODH is found, ZF = 1, and DI
will point at the next byte after the carriage return in the string. If a carriage
return is not found, then CX = 0 and ZF = 0. The assembler uses the name of the
string to determine whether the string is of type byte or type word. Instead of
using the name, we can tell the assembler the type of string directly by using the
mnemonic SCASB for a byte string and SCASW for a word string.

CMPS/CMPSB/CMPSW-Compare String Bytes or String Words


A string is a series of the same type of data items in sequential memory
locations. The CMPS instruction can be used to compare a byte in one string with
a byte in another string or to compare a word in one string with a word in
another string. SI is used to hold the offset of a byte or word in the source string,
and DI is used to hold the offset of a byte or a word in the other string.
The comparison is done by subtracting the byte or word pointed to by DI
from the byte or word pointed to by SI. The AF, CF, OF, PF, SF, and ZF flags are
affected by the comparison, but neither operand is affected. After the
comparison, SI and DI will automatically be incremented or decremented to
point to the next elements in the two strings. If the direction flag has previously

37
Chapter 2 Assembly Language Programming

been set to a 1 with an STD instruction, then SI and DI will automatically be


decremented by 1 for a byte string or by 2 for a word string. If the direction flag
has previously been reset to a 0 with a CLD instruction, then SI and DI will
automatically be incremented after the compare. They will be incremented by 1
for byte strings and by 2 for word strings.
The string pointed to by DI must be in the extra segment. The string
pointed to by SI must be in the data segment.
The CMPS instruction can be used with a REPE or REPNE prefix to
compare all the elements of a string.

EXAMPLE:
MOV SI, OFFSET FIRST-STRING Point SI at source string
MOV DI, OFFSET SECOND-STRING Point DI at destination string
CLD DF cleared, so SI and DI will auto
increment after compare
MOV CX,100 Put number of string elements in CX
REPE CMPSB Repeat the comparison of string bytes
until end of string or until compared
bytes are not equal
NOTE: CX functions as a counter, which, the REPE prefix will cause to be
decremented after each compare. The B attached to CMPS tells the assembler that
the strings are of type byte. If we want to tell the assembler that the strings are of
type word, write the instruction as CMPSW. The REPE CMPSW instruction will
cause the pointers in SI and DI to be incremented by 2 after each compare if the
direction flag is cleared or decremented by 2 if the direction flag is set.

REP/REPE/REPZ/REPNE/REPNZ- (Prefix) Repeat String Instruction until


Specified Conditions Exist
REP is a prefix, which is written before one of the string instructions. It
will cause the CX register to be decremented and the string instruction to be
repeated until CX = 0. The instruction REP MOVSB, for example, will continue to
copy string bytes until the number -of bytes loaded into CX has been copied.
REPE and REPZ are two mnemonics for the same prefix. They stand for
Repeat if Equal and Repeat if Zero, respectively. We can use whichever prefix
makes the operation clearer to we in a given program. REPE or REPZ is often
used with the Compare String instruction or with the Scan String instruction.
REPE or REPZ will cause the string instruction to be repeated as long as the
compared bytes or words are equal (ZF = 1) and CX is not yet counted down to
zero. In other words, there are two conditions that will stop the repetition: CX = 0
or string bytes or words not equal.

EXAMPLE:

38
Chapter 2 Assembly Language Programming

REPE CMPSB, Compare string bytes until end of string or until string bytes not
equal. See the discussion of the CMPS instruction for a more detailed example of
the use of REPE.
REPNE and REPNZ are also two mnemonics for the same prefix. They stand for
Repeat if Not Equal and Repeat if Not Zero, respectively. REPNE or REPNZ is
often used with the Scan String instruction. RFPNE or REPNZ will cause the
string instruction to be repeated until the compared bytes or words are equal (ZF
= 1) or until CX = 0 (end of string).
REPNE SCASW, Scan a string of words until a word in the string matches the
word in AX or until all of the string has been scanned. See the discussion of
SCAS for a more detailed example of the use of this prefix
The string instruction used with the prefix determines which flags are
affected. See the individual instructions for this information.
NOTE: Interrupts should be disabled when multiple prefixes are used, such as
LOCK, segment override, and REP with string instructions on the 8086/8088.
This is because, during an interrupt response, the 8086 can remember only the
prefix just before the string instruction. The 80186, 80286, etc., will remember all
the prefixes and start up correctly after an interrupt during a string instruction.

2.3.6 Program Execution Transfer Instructions


2.4.6.1 Unconditional Transfer Instructions

CALL--Call a Procedure
The CALL instruction is used to transfer execution to a subprogram or
procedure. There are two basic types of calls, near and far. A near call is a call to
a procedure, which is in the same code segment as the CALL instruction. When
the 8086 executes a near CALL instruction, it decrements the stack pointer by 2
and copies the offset of the next instruction after the CALL onto the stack. This
offset saved on the stack is referred to as the return address, because this is the
address that execution will return to after the procedure executes. A near CALL
instruction will also load the instruction pointer with the offset of the first
instruction in the procedure. A RFT instruction at the end of the procedure will
return execution to the instruction after the call by copying the offset saved on
the stack back to IP.
A far call is a call to a procedure, which is in a different segment from the
one that contains the CALL instruction. When the 8086 executes a far call, it
decrements the stack pointer by 2 and copies the contents of the CS register to the
stack. It then decrements the stack pointer by 2 again and copies the offset of the
instruction after the CALL instruction to the stack. Finally, it loads CS with the
segment base of the segment, which contains the procedure, and loads IP with
the offset of the first instruction of the procedure in that segment. A RFT
instruction at the end of the procedure will return execution to the next

39
Chapter 2 Assembly Language Programming

Instruction after the CALL by restoring the saved values of CS and IP from the
stack.
EXAMPLES:
CALL MULTO A direct within-segment (near or intra- segment) call. MULTO
is the name of the procedure. The assembler determines the displacement of
MULTO from the instruction after the CALL and codes this displacement in as
part of the instruction.
CALL BX An indirect within-segment near or intrasegment call. BX
contains the offset of the first instruction of the procedure. Replaces contents of
IP with contents of register BX.
CALL WORD PTR [BX] An indirect within-segment near or intrasegment
call. Offset of first instruction of procedure is in two memory addresses in DS.
Replaces contents of IP with contents of word memory location in DS pointed to
by BX.
CALL SMART_DIVIDE A direct call to another segment-far or intersegment
call. SMART_DIVIDE is the name of the procedure. The procedure must be
declared far with SMART_DIVIDE PROC FAR at its start. The assembler will
determine the code segment base for the segment, which contains the procedure
and the offset of the start of the procedure. It will put these values in as part of
the instruction code.
CALL DWORD PTR [BX] An indirect call to another segment-far or
intersegment call. New values for CS and IP are fetched from four memory
locations in DS. The new value for CS is fetched from [BX] and [BX + 1]; the new
IP is fetched from [BX + 2] and [BX + 3].

RETǦReturnExecutionfromProceduretoCallingProgram
The RET instruction will return execution from a procedure to the next
instruction after the CALL instruction which was used to CALL the procedure. If
the procedure is a near procedure (in the same code segment as the CALL
instruction), then the return will be done by replacing the instruction pointer
with a word from the top of the stack. The word from the top of the stack is the
offset of the next instruction after the CALL. This offset was pushed onto the
stack as part of the operation of the CALL instruction. The stack pointer will be
incremented by 2 after the return address is popped off the stack.
If the procedure is a far procedure (in a different code segment from the
CALL instruction which calls it), then the instruction pointer will be replaced by
the word at the top of the stack. This word is the offset part of the return address
put there by the CALL instruction. The stack pointer will then be incremented
by 2. The code segment register is then replaced with a word from the new top of
the stack. This word is the segment base part of the return address that was
pushed on to the stack by a far call operation. After the code segment word is
popped off the stack, the stack pointer is again incremented by 2.

40
Chapter 2 Assembly Language Programming

A RET instruction can be followed by a number, for example, RET 6. In this case
the stack pointer will be incremented by an additional six addresses after the IP
or the IP and CS are popped off the stack. This form is used to increment the
stack pointer over parameters passed to the procedure on the stack. The RET
instruction affects no flags.

JMP-Unconditional jump to Specified Destination


This instruction will always cause the 8086 to fetch its next Instruction
from the location specified in the instruction rather than from the next location
after the JMP instruction. If the destination is in the same code segment as the
JMP instruction, then only the instruction pointer will be changed to get to the
destination location. This is referred to as a nearjump. If the destination for the
jump instruction is in a segment with a name different from that of the segment
containing the JMP instruction, then both the instruction pointer and the code
segment register contents will be changed to get to the destination location. This
is referred to as a farjump. The JMP instruction affects no flags.
EXAMPLES:
JMP CONTINUE; Fetch next instruction from address at label CONTINUE. If
the label is in the same segment, an offset coded as part of the instruction will be
added to the instruction pointer to produce the new fetch address. If the label is
in another segment, then IP and CS will be replaced with values coded in as part
of the instruction. This type of jump is referred to as direct because the
displacement of the destination or the destination itself is specified directly in the
instruction.
JMP BX ; Replace the contents of IP with the contents of BX. BX must first be
loaded with the offset of the destination instruction in CS. This is a near jump. It
is also referred to as an indirect jump because the new value for IP comes from a
register rather than from the instruction itself, as in a direct jump.
JMP WORD PTR [BX] ; Replace IP with a word from a memory location pointed
to by BX in DS. This is an indirect near jump.
JMP DWORD PTR [ SI], Replace IP with a word pointed to by SI in DS. Replace
CS with a word pointed to by SI + 2 in DS. This is an indirect far jump.

2.3.6.2 Conditional Transfer Instructions


JA/JNBE-Jump if Above/jump if Not Below or Equal
These two mnemonics represent the same instruction. The terms above
and below are used when referring to the magnitude of unsigned numbers. The
number 0111 is above the number 0010. If, after a compare or some other
instruction which affects flags, the zero flag and the carry flag are both 0. This
instruction will cause execution to jump to a label given in the instruction. If CF
and ZF are not both 0, the instruction will have no effect on program execution.

41
Chapter 2 Assembly Language Programming

The destination label for the jump must be in the range of - 128 bytes to + 127
bytes from the address of the Instruction after the JA. JA/JNBE affects no flags.

 
CMP AX, 4371H Compare by subtracting 4371H from AX
JA RUN-PRFSS Jump to label RUN-PRFSS if AX above 4371H
CMP AX, 4371H Compare (AX - 4371H)
JNBE RUN_PRESS JUMP to label RUN_PRESS if AX not below or equal
to 4371H
ADD AL, BL Add two bytes. If the result within acceptable range
JNC OK Continue

JAE/INB/INCǦǦJumpifAboveorEqual/jumpifNotBelow/jumpifNoCarry
These three mnemonics represent the same instruction. The terms above
and below are used when referring to the magnitude of unsigned numbers. The
number 0111 is above the number 0010. If, after a compare or some other
instruction, which affects flags, the carry flag is 0, this instruction will cause
execution to jump to a label given in the instruction. If CF is 1, the instruction
will have no effect on program execution. The destination label for the jump
must be in the range of - 128 bytes to +I 127 bytes from the address of the
instruction after the JAE. JAE/JNB/JNC affects no flags.
EXAMPLES:
CMP AX, 4371H Compare (AX - 4371H)
JAE RUN_PRESS Jump to label RUN_PRESS if AX above or equal to 4371H
CMP AX, 4371H Compare (AX - 4371H)
JNB RUN_PRESS Jump to label RUN-PRESS if AX not below 4371H
ADD AL, BL Add two bytes. If result within JNC OK
acceptable range, continue.

JB/JC/JNAEǦjumpifBelow/jumpifCarry/jumpifNotAboveorEqual
These three mnemonics represent the same instruction. The terms above
and below are used when referring to the magnitude of unsigned numbers. The
number 0111 is above the number 0010. If, after a compare or some other
instruction, which affects flags, the carry flag is a 1, this instruction will cause
execution to jump to a label given in the instruction. If CF is 0, the instruction
will have no effect on program execution. The destination label for the jump
must be in the range of - 128 bytes to + 127 bytes from the address of the
instruction after the JB. JB/JC/JNAE affects no flags.
EXAMPLES:
CMP AX, 4371H Compare (AX - 4371H)
JB RUN_PRFSS Jump to label RLIN-PRFSS if AX below 4371H
ADD BX, CX Add two words and jump
JC ERROR_FIX to label ERROR-FIX if CF = 1

42
Chapter 2 Assembly Language Programming

CMP AX, 4371H Compare (AX - 4371H)


JNAE RUN_PRESS Jump to label RUN-PRESS if AX not above or equal to 4371H

JBE/JNAǦJumpifBeloworEqual/JumpifNotAbove
These two mnemonics represent the same Instruction. The terms above
and below are used when referring to the magnitude of unsigned numbers. The
number 0111 is above the number 0010. If, after a compare or some other
instruction, which affects flags, the zero, flag or the carry flag is 1, this instruction
will cause execution to jump to a label given in the instruction. If CF and ZF are
both 0, the instruction will have no effect on program execution. The destination
label for the jump must be in the range of - 128 bytes to + 127 bytes from the
address of the instruction after the JBE. JBE/JNA affects no flags.
EXAMPLES:
CMP AX, 4371H Compare (AX - 4371H)
JBE RUN-PRESS Jump to label RUN-PRESS if AX below or equal to 4371H
CMPAX, 4371H Compare (AX - 4371H)
JNA RUN-PRESS Jump to label RUN-PRESS if AX not above 4371H

JE/JZǦJumpifEqual/jumpifZero
These two mnemonics represent the same Instruction. If the zero flag is
set, then this instruction will cause execution to jump to a label given In the
instruction. If the zero flag is not 1, then execution will simply go on to the next
instruction after JE or JZ. The destination label for the JE/JZ instruction must be
in the range of - 128 to + 127 bytes from the address of the instruction after the
JE/JZ instruction. JE/JZ affects no flags.
EXAMPLES:
NXT:CMP BX,DX Compare (BX-DX)
JE DONE Jump to DONE if BX = DX
SUB BX,AX Else subtract AX
INC CX Increment counter
JMP NXT Check again
DONE:MOV AX,CX Copy count to AX
IN AL,8FH Read data from port 8FH
SUB AL,30H Subtract minimum value
JZ START_MACHINE Jump to label if result of subtraction was 0

JG/JNLEǦJumpifGreater/JumpifNotLessThanorEqual
These two mnemonics represent the same Instruction. The terms greater
and less are used to refer to the relationship of two signed numbers. Greater
means more positive. The number 0000 0111 is greater than the number 1110
1010, because in signed notation the second number is negative. This instruction
is usually used after a Compare instruction. The Instruction will cause a jump to

43
Chapter 2 Assembly Language Programming

a label given in the Instruction if the zero flag is 0 and the carry flag is the same
as the overflow flag. The destination label must be in the range of - 128 bytes to +
127 bytes from the address of the instruction after the JG/JNLE instruction. If the
jump is not taken, execution simply goes on to the next instruction after the JG or
JNLE instruction. JG/JNLE affects no flags.

Other Jump Instructions:


JGE/JNL-Jump if Greater Than or Equal/Jump if Not Less Than

JL/JNGEǦjumpifLessThan/jumpifNotGreaterThanorEqual

JLE/JNGǦjumpifLessThanorEqual/JumpifNotGreater

JMP-Unconditional jump to Specified Destination


This instruction will always cause the 8086 to fetch its next Instruction
from the location specified in the instruction rather than from the next location
after the JMP instruction. If the destination is in the same code segment as the
JMP instruction, then only the instruction pointer will be changed to get to the
destination location. This is referred to as a nearjump. If the destination for the
jump instruction is in a segment with a name different from that of the segment
containing the JMP instruction, then both the instruction pointer and the code
segment register contents will be changed to get to the destination location. This
is referred to as a farjump. The JMP instruction affects no flags.
EXAMPLES:
JMP CONTINUE; Fetch next instruction from address at label CONTINUE. If
the label is in the same segment, an offset coded as part of the instruction will be
added to the instruction pointer to produce the new fetch address. If the label is
in another segment, then IP and CS will be replaced with values coded in as part
of the instruction. This type of jump is referred to as direct because the
displacement of the destination or the destination itself is specified directly in the
instruction.
JMP BX ; Replace the contents of IP with the contents of BX. BX must first be
loaded with the offset of the destination instruction in CS. This is a near jump. It
is also referred to as an indirect jump because the new value for IP comes from a
register rather than from the instruction itself, as in a direct jump.
JMP WORD PTR [BX] ; Replace IP with a word from a memory location pointed
to by BX in DS. This is an indirect near jump.
JMP DWORD PTR [ SI], Replace IP with a word pointed to by SI in DS. Replace
CS with a word pointed to by SI + 2 in DS. This is an indirect far jump.

JNE/JNZ-Jump if Not Equal/Jump if Not Zero


If the zero flag is 0, then this instruction will cause execution to jump to a
label given in the instruction. If the zero flag is 1, then execution will simply go

44
Chapter 2 Assembly Language Programming

on to the next instruction after JNE or JNZ. The destination label for the
JNE/JNZ instruction must be in the range of - 128 to + 127 bytes from the
address of the instruction after the JNE/JNZ instruction. JNE/JNZ affects no
flags.

JNP/JPOǦJumpifNoParity/JumpifParityOdd
If the number of 1's left in the lower 8 bits of a data word after an instruction
which affects the parity flag is odd, then the parity flag will be 0. The JNP/JPO
instruction will cause execution to jump to a specified destination address if the
parity flag is 0. The destination address must be in the range of - 128 bytes to +
127 bytes from the address of the instruction after the JNP/ JPO instruction.

JNS-jump if Not Signed (Jump if Positive)


This instruction will cause execution to jump to a specified destination. If
the sign flag is 0. Since a 0 in the sign flag indicates a positive signed number, we
can think of this instruction as saying "jump if positive. " If the sign flag is set,
indicating a negative signed result, execution will simply go on to the next
instruction after JNS. The destination for the jump must be in the range of - 128
bytes to + 127 bytes from the address of the instruction after the JNS. JNS affects
no flags.

JOǦjumpifOverflow
The JO instruction will cause the 8086 to jump to a destination given in the
instruction if the overflow flag is set. The overflow flag will be set if the
magnitude of the result produced by some signed arithmetic operation is too
large to fit in the destination register or memory location. The destination for the
JO instruction must be in the range of - 128 bytes to + 127 bytes from the address
of the instruction after the JO instruction. If the overflow flag is not set, execution
will simply continue with the next instruction after JO. JO affects no flags.

JP/JPEǦJumpifParity/jumpifParityEven
If the number of 1's left In the lower 8 bits of a data word after an
instruction which affects the parity flag is even, then the parity flag will be set. If
the parity flag is set, the JP/JPE instruction will cause execution to jump to a
specified destination address. If the parity flag is 0, execution will simply
continue on to the instruction after the JP/JPE instruction. The destination
address must be in the range of - 128 bytes to + 127 bytes from the address of the
instruction after the JP/JPE instruction. The JP/JPE instruction affects no flags.

JS--Jump If Signed (jump if Negative)


This instruction will cause execution to jump to a specified destination if the sign
flag is set. Since a 1 in the sign flag indicates a negative signed number, we can
think of this instruction as saying "jump if negative" or "Jump if minus." If the

45
Chapter 2 Assembly Language Programming

sign flag is 0, indicating a positive signed result, execution will simply go on to


the next instruction after JS. The destination for the jump must be in the range of
- 128 bytes to + 127 bytes from the address of the instruction after the JS. JS
affects no flags.

2.3.6.3. Iteration Control Instructions:


LOOPǦjumptoSpecifiedLabelifCXβ0afterAutodecrementǦǦǦLOOPLabel
This instruction is used to repeat a series of instructions some number of
times. The number of times the instruction sequence is to be repeated is loaded
into CX. Each time the LOOP instruction executes, CX is automatically
decremented by 1. If CX is not 0, execution will jump to a destination specified
by a label in the instruction. If CX = 0 after the autodecrement, execution will
simply go on to the next instruction after LOOP. The destination address for the
jump must be in the range of - 128 bytes to + 127 bytes from the address of the
instruction after the LOOP instruction. LOOP affects no flags.
EXAMPLE:
MOV BX, OFFSET PRICES Point BX at first element in array
MOV CX.40 Load CX with number of elements in array
NEXT: MOV AL, [BX] Get element from array
ADD AL, 07H Add correction factor
DAA Decimal adjust result
MOV [BX],AL Put result back in array, INC BX
LOOP NEXT Repeat until all elements adjusted

LOOPE/LOOPZǦǦǦLoopWhileCXβ0andZF=1
LOOPE and LOOPZ are two mnemonics for the same instruction. This
instruction is used to repeat a group of instructions some number of times or
until the zero flags becomes 0. The number of times the instruction sequence is to
be repeated is loaded into CX. Each time the LOOP instruction executes, CX is
automatically decremented by 1. If CX = 0 and ZF = 1, execution will jump to a
destination specified by a label in the instruction. If CX = 0 after the
autodecrement or if ZF = 0, execution will simply go on to the next instruction
after LOOPE/LOOPZ. In other words, the two ways to exit the loop are CX = 0
or ZF = 0. The destination address for the jump must be in the range of - 128
bytes to + 127 bytes from the address of the instruction after the LOOPE/LOOPZ
instruction. LOOPE/LOOPZ affects no flags.
EXAMPLE:
MOV BX, OFFSET ARRAY Point BX to just
DEC BX before start of array
MOV CX, 100 Put number of array elements in CX
NEXT: INC BX Point to next element in array

46
Chapter 2 Assembly Language Programming

CMP [BX], 0FFH Compare array element with FFH


LOOPE NEXT
NOTE: The next element is checked if the element equals FFH and the element
was not the last one in the array. If CX = 0 and ZF = 1 on exit, all elements were
equal to FFH. If CX= 0 on exit from the loop, then BX points to the first element
that was not FFH. If CX = 0 and ZF = 0 on exit, then the last element was not
FFH.

LOOPNE/LOOPNZǦǦǦLoopWhileCXβ0andZF=0
LOOPNE and LOOPNZ are two mnemonics for the same instruction. This
instruction is used to repeat a group of instructions some number of times or
until the zero flag becomes a 1. The number of times the instruction sequence is
to be repeated is loaded into the count register CX. Each time the
LOOPNE/LOOPNZ instruction executes, CX is automatically decremented by 1.
If CX  0 and ZF = 0, execution will jump to a destination specified by a label in
the Instruction. If CX = 0 after the autodecrement or if ZF = 1, execution will
simply go on to the next instruction after LOOPNE/LOOPNZ.

JCXZǦJumpiftheCXRegisterIsZero
This instruction will cause a jump to a label given in the Instruction if the
CX register contains all 0's. If CX does not contain all 0's, execution will simply
proceed to the next instruction. Note that this instruction does not look at the
zero flag when it decides whether to jump or not. The destination label for this
instruction must be in the range of - 128 to + 127 bytes from the address of the
instruction after the JCXZ instruction. JCXZ affects no flags.
EXAMPLE:
JCXZ SKIP_LOOP If CX = 0, skip the process
NXT: SUB [BX], 07H Subtract 7 from data value
INC BX Point to next value
LOOP NXT Loop until CX = 0
SKIP_LOOP: Next instruction

2.3.6.4 Interrupt Instructions

INT-interrupt Program Execution-INT Type


The term type in the instruction format refers to a number between 0 and
255 which identifies the interrupt. When an 8086 executes an INT instruction, it
will:
1. Decrement the stack pointer by 2 and push- the flags onto the stack.

47
Chapter 2 Assembly Language Programming

2. Decrement the stack pointer by 2 and push the contents of CS onto the
stack.
3. Decrement the stack pointer by 2 and push the offset of the next
instruction after the TNT number Instruction on the stack.
4. Get a new value for IP from an absolute memory address of 4 times the
type specified in the instruction. For an INT 8 Instruction, for example, the
new IP will be read from address 00020H.
5. Get a new value for CS from an absolute memory address of 4 times the
type specified in the instruction plus 2. For an INT 8 instruction, for
example, the new value of CS will be read from address 00022H.
6. Reset both IF and TF. Other flags are not affected.

EXAMPLES:
INT 35 New IP from 0008CH, new CS from 0008EH
INT 3 This is a special form, which has the single-byte code of CCH.
Many systems use this as a breakpoint Instruction. New IP from 0000CH, new CS
from 0000EH.

INTOǦinterruptonOverflow
If the overflow flag (OF) is set, this instruction will cause the 8086 to do an
indirect far call to a procedure we write to handle the overflow condition. Before
doing the call, the 8086 will:
1. Decrement the stack pointer by 2 and push the flags onto the stack.
2. Decrement the stack pointer, by 2 and push CS onto the stack.
3. Decrement the stack pointer by 2 and push the offset of the next instruction
after the INTO instruction onto the stack
4. Reset TF and IF. Other flags are not affected. To do the call, the 8086 will read
a new value for IP from address 00010H and a new value of CS from address
00012H.
EXAMPLE:
INTO Call interrupt procedure if OF = 1

IRET-interrupt Return
When the 8086 responds to an interrupt signal or to an interrupt
instruction, it pushes the flags, the current value of CS, and the current value of
IP onto the stack. It then loads CS and IP with the starting address of the
procedure, which we write for the response to that Interrupt. The IRET
Instruction is used at the end of the interrupt service procedure to return
execution to the interrupted program. To do this return, the 8086 copies the
saved value of IP from the stack to IP, the stored value of CS from the stack to
CS, and the stored value of the flags back to the flag register. Flags will have the
values they had before the interrupt, so any flag settings from the procedure will
be lost unless they are specifically saved in some way.

48
Chapter 2 Assembly Language Programming

NOTE: The RET instruction should not normally be used to return from interrupt
procedures because it does not copy the flags from the stack back to the flag
register.
2.3.7 Process Control Instructions
2.3.7.1. Flag Set/clear Instructions

STC-Set the Carry Flag to a 1


STC does not affect any other flags.
CLC-Clear the Carry Flag (CF)
This instruction resets the carry flag to 0. No other flags are affected.
CMC-Complement the Carry Flag
If the carry flag (CF) is a 0 before this instruction, it will be set to a 1 after
the instruction. If the carry flag is1before this instruction, it will be reset to a 0
after the instruction executes. CMC affects no other flags.
EXAMPLE:
CMC, Invert the carry flag

STD-Set the Direction Flag to a 1


STD is used to set the direction flag to a 1 so that SI and/or DI will
automatically be decremented to point to the next string element when one of the
string instructions executes. If the direction flag is set, SI and/or DI will be
decremented by 1 for byte strings, and by 2 for word strings. STD affects no other
flags.

CLDǦClearDirectionFlag
This instruction resets the direction flag to 0. No other flags are affected. If
the direction flag is reset, SI and DI will automatically be incremented when one
of the string instructions, such as MOVS, CMPS, or SCAS, executes.
EXAMPLE:
CLD Clear direction flag so that string pointers auto increment after each string
operation
STI-Set Interrupt Flag (IF)

Setting the interrupt flag to a 1 enables the INTR interrupt input of the
8086. The instruction will not take effect until after the next instruction after STI.
When the INTR input is enabled, an interrupt signal on this input will then cause
the 8086 to interrupt program execution, push the return address and flags on
the stack, and execute an interrupt service procedure. An IRET instruction at the
end of the interrupt service procedure will restore the flags, which were pushed
onto the stack, and return execution to the interrupted program. STI does, not
affect any other flags.

49
Chapter 2 Assembly Language Programming

CLIǦClearInterruptFlag
This instruction resets the interrupt flag to 0. No other flags are affected. If
the interrupt flag is reset, the 8086 will not respond to an interrupt signal on its
INTR input. The CLI instruction, however, has no effect on the non-maskable
interrupt input, NMI.

2.3.7.2. External Hardware Synchronization Instructions


HLTǦHaltProcessing
The HLT instruction will cause the 8086 to stop fetching and executing
instructions. The 8086 will enter a halt state. The only ways to get the processor
out of the halt state are with an interrupt signal on the INTR pin, an interrupt
signal on the NMI pin, or a reset signal on the RESET input.

WAITǦWaitforTestSignalorinterruptSignal
When this instruction executes, the 8086 enters an idle condition in which
it is doing no processing. The 8086 will stay in this idle state until the 8086 TEST
input pin is made low or until an interrupt signal is received on the INTR or the
NMI interrupt input pins. If a valid interrupt occurs while the 8086 is in this idle
state, the 8086 will return to the idle state after the interrupt service procedure
executes. It returns to the idle state because the address of the WAIT instruction
is the address pushed on the stack when the 8086 responds to the interrupt
request. WAIT affects no flags. The WAIT instruction is used to synchronize the
8086 with external hardware such as the 8087-math coprocessor.

ESCǦEscape
This instruction is used to pass instructions to a coprocessor, such as the
8087-math coprocessor, which shares the address and data bus with an 8086.
Instructions for the coprocessor are represented by a 6-bit code embedded in the
escape instruction. As the 8086 fetches instruction bytes, the coprocessor also
catches these bytes from the data bus and puts them in its queue. However, the
coprocessor treats all the normal 8086 instructions as NOPs. When the 8086
fetches an ESC instruction, the coprocessor decodes the instruction and carries
out the action specified by the 6-bit code specified in the instruction. In most
cases the 8086 treats the ESC instruction as a NOP. In some cases the 8086 will
access a data item in memory for the coprocessor.

LOCKǦAssertBusLockSignal
Many microcomputer systems contain several microprocessors. Each
microprocessor has its own local buses and memory. The individual
microprocessors are connected together by a system bus so that each can access
system resources such as disk drives or memory. Each microprocessor takes
control of the system bus only when it needs to access some system resource. The

50
Chapter 2 Assembly Language Programming

LOCK prefix allows a microprocessor to make sure that another processor does
not take control of the system bus while it is in the middle of a critical instruction
which uses the system bus. The LOCK prefix is put in front of the critical
instruction. When an instruction with a LOCK prefix executes, the 8086 will
assert its bus lock signal output. This signal is connected to an external bus
controller device, which then prevents any other processor from taking over the
system bus. LOCK affects no flags.
EXAMPLE:
LOCK XCHG SEMAPHORE, AL The XCHG instruction requires two bus
accesses. The LOCK prefix prevents another processor from taking control of the
system bus between the two accesses.

2.4.7.3 No Operation Instruction

NOPǦPerformNoOperation
This instruction simply uses up three clock cycles and Increments the instruction
pointer to point to the next instruction. NOP affects no flags. The NOP
instruction can be used to increase the delay of a delay loop. When hand coding
a NOP can also be used to hold a place in a program for an instruction that will
be added later.

2.4. ASSEMBLER DIRECTIVES AND OPERATORS


The words defined in this section are directions to the assembler, not
instructions for the 8086. The assembler directives described here are those for
the Intel 8086 macro-assembler (ASM86), the Borland Turbo Assembler (TASM),
and the IBM macro assembler (MASM). If we are using some other assembler,
consult the manual for it to find the corresponding directives.

ASSUME
The ASSUME directive is used to tell the assembler the name of the logical
segment it should use for a specified segment. The statement ASSUME CS:
CODE, for example, tells the assembler that the instructions for a program are in
a logical segment named CODE. The statement ASSUME DS: DATA tells the
assembler that for any program instruction, which refers to the data segment, it
should use the logical segment called DATA. If, for example, the assembler reads
the statement MOV AX,[BX] after it reads this ASSUME, it will know that the
memory location referred to by [BX] is in the logical segment DATA. We must
tell the assembler what to assume for any segment we use in a program. If we
use a stack in our program, we must tell the assembler the name of the logical
segment we have set up as a stack with a statement such as ASSUME SS:
STACK_HERE. For a program with string Instructions which use DI, the

51
Chapter 2 Assembly Language Programming

assembler must be told what to assume for the extra segment with a statement
such as ASSUME ES: STRING_DESTINATION.
DB--Define Byte
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. The statement
CURRENT_TEMPERATURE DB 42H, for example, tells the assembler to reserve
1 byte of memory for a variable named CURRENT_TEMPERATURE and to put
the value 42H in that memory location when the program is loaded into RAM to
be run.
Here are a few more examples of DB statements.
PRICES DB 49H, 98H, 29H Declare array of 3 bytes named-
PRICES and initialize 3 bytes as shown.
NAME_HERE DB 'YOHANNAS' ; Declare array of 6 bytes and initialize
with ASCII codes for letters in YOHANNAS.
TEMPERATURE-STORAGE DB 100 DUP(?) ; Set aside 100 bytes of storage in
memory and give it the name TEMPERATURE_STORAGE, but leave the 100
bytes uninitialized. Program instructions will load values into these locations.
PRESSURE_STORAGE DB 20H DUP(0) ; Set aside 20H bytes of storage in
memory, give it the name PRESSURE_STORAGE, and put 0 in a 20H locations.

DDǦDefineDoubleword
The DD directive is used to declare a variable of type doubleword or to,
reserve memory locations, which can be accessed as type doubleword. The
statement ARRAY_POINTER DD 25629261H, for example, will define a
doubleword named ARRAY_POINTER and initialize the doubleword with the
specified value when the pro- gram is loaded into memory to be run. The low
word, 9261H, will be put in memory at a lower address than the high word. A
declaration of this type is often used with the LES or LDS instruction. The
Instruction LES DI, ARRAY_POINTER, for example, will copy the low word of
this doubleword, 9261H, into the DI register and the high word of the
doubleword, 2562H, into the extra segment register.

DQǦdefineQuadword
This directive is used to tell the assembler to declare a variable 4 words in
length or to reserve 4 words of storage in memory.
The statement BIG_NUMBER DQ 243598740192A92BH, for example, will
declare a variable named BIG_NUMBER and initialize the 4 words set aside with
the specified number when the program is loaded into memory to be run. The
statement STORAGE DQ 100 DUP (0) reserves 100 quadwords of storage and
initializes them all to 0 when the program is loaded into memory to be run.

52
Chapter 2 Assembly Language Programming

DTǦDefineTenBytes
DT is used to tell the assembler to define a variable, which is 10 bytes in
length, or to reserve 10 bytes of storage in memory.
The statement PACKED_BCD DT 11223344556677889900 will declare an
array named PACKED_BCD, which is 10 bytes in length. It will initialize the 10
bytes with the values 11223344556677889900 when the program is loaded into
memory to be run. This directive is often used when declaring data arrays for the
8087 math coprocessor. The statement RESULTS DT 20H DUP (0) will declare an
array of 20H blocks of 10 bytes each and initialize all 320 bytes to 00 when the
program is loaded into memory to be run.

DWǦDefineWord
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. The statement
MULTIPLIER DW 437AH, for example, declares a variable of type word named
MULTIPLIER. The statement also tells the assembler that the variable
MULTIPLIER should be initialized with the value 437AH when the program is
loaded into memory to be run.
Few more examples of DW statements.
THREE_LITFLE_WORDS DW 1234H,3456H,5678H ;Declare array of 3 words
and initialize with specified values.
STORAGE DW 100 DUP(0) ; Reserve an array of 100 words of memory and
initialize all100 words with 0000. Array is named STORAGE.
STORAGEDW 100 DUP(?) ; Reserve 100 words of storage in memory and
give it the name STORAGE, but leave the words uninitialized.

ENDǦEndProgram
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 assembler will ignore
any statements after an END directive, so we should make sure to use only one
END directive at the very end of our program module. A carriage return is
required after the END directive.

ENDPǦEndProcedure
This directive is used along with the name of the procedure to indicate the
end of a procedure to the assembler. This directive, together with the procedure
directive, PROC, is used to "bracket" a procedure. Here's an example.
SQUARE-ROOT PROC Start of procedure
//Procedure instruction statements
SQUARE-ROOT ENDP End of procedure

53
Chapter 2 Assembly Language Programming

ENDSǦEndSegment
This directive is used with the name of a segment to indicate the end of
that logical segment. ENDS is used with the SEGMENT directive to "bracket" a
logical segment containing instructions or data. Here's an example.
CODE SEGMENT Start of logical segment containing code
//Instruction statements
CODE ENDS End of segment named CODE

EQUǦEquate
EQU is used to give a name to some value or symbol. Each, time the
assembler finds the given name in the program, it will replace the name with the
value or symbol we equated with that name. Suppose, for example, we write the
statement CORRECTION_FACTOR EQU 03H at the start of our program, and
later in the program we write the instruction statement ADD AL,
CORRECTION_ACTOR. When it codes this instruction statement, the assembler
will code it as if we had written the instruction ADD AL, 03H. The advantage of
using EQU in this manner is that if CORRFCTION_FACTOR is used 27 times in
a program, and we want to change the value, all we have to do is change the
EQU statement and reassemble the program. The assembler will automatically
put in the new value each time it finds the name CORRECTION_FACTOR. If we
had used 03H Instead of the EQU approach, then we would have had to try to
find all 27 instructions and change them ourself. Here are some more examples.

CONTROL_WORD EQU 11001001 Replacement


MOV AL, CONTROL_WORD assignment
DECIMAL_ADJUST EQU DAA Create clearer mnemonic for DAA
ADD AL,BL Add BCD numbers
DECIMAL_ADJUST Keep result in BCD format
STRING_START EQU [BX] Give name to [BX]
EVEN-Align on Even Memory Address
As the assembler assembles a section of data declarations or instruction
statements, it uses a location counter to keep track of how many bytes it is from
the start of a segment at any time. 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. The 8086 can read a word from memory in one bus cycle if the
word is at an even address. If the word starts at an odd address, the 8086 must
do two bus cycles to get the 2 bytes of the word. Therefore, a series of words can
be read much more quickly if they are at even addresses. When EVEN is used in
a data segment, the location counter will simply be incremented to the next even
address if necessary. When EVEN is used in a code segment, the location counter
will be incremented to the next even address if necessary. A NOP instruction will
be inserted in the location incremented over.

54
Chapter 2 Assembly Language Programming

Other Assembler Directives (Details of these will be discussed in the class.)


EXTRN—is used to tell the assembler that the names or labels following the
directive are in some other assembly module.
GLOBAL—This directive can be used in place of PUBLIC directive or in place of
an EXTRN directive. The GOLBAL directive is used to make the symbol
available to other modules.
GROUP—This is used to tell the assembler to group the logical segments named
after the directive into one logical group segment.
INCLUDE—Include Source Code from File: This is used to tell the assembler to
insert a block of source code from the named file in to the current source
module.
LENGTH—Is an operator, which tells the assembler to determine the number of
elements in some named data item, such as a string of an array. When the
assembler reads the statement MOV CX, LENGTH STRING1 , example it will
determine the number of elements in STRING1.
NAME-- This directive is used to give a specific name to each assembly module
when programs consisting of several modules are written.
OFFSET—Is an operator which tells the assembler to determine the offset or the
displacement of a named data item (variable) or procedure from start of the
segment which contains it. This operator is used to load the offset of a variable
into a register so that the variable can be accessed with one of the indexed
addressing modes.
ORG – This directives allows we to set the location counter to a desired value at
any point in the program. The statement ORG 100H tells the assembler to set the
location counter to 0100H.
A ‘$’ is oftern used to symbolically represent the current value of the location
counter. The ‘$’ actually represents the next available byte location where the
assembler can put a data or code byte.
ORG $ +100 tells the assembler to increment the value of the location counter
by 100 from its current value. A statement such as this can be used in a data
segment to leave 100 bytes of space for future use.
PROC—Is used to identify the start of a procedure.
PTR—It 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.
INC BYTE PTR[BX]
INC WORD PTR[BX]
MOV AL,BYTE PTR WORDS.
PUBLIC—directive is used to tell the assembler that a specified name or label
will be accessed from other modules.
SEGMENT—It is used to indicate the start of a logical segment. Preceding the
SEGMENT directive is the name we want to give the segment.

55
Chapter 2 Assembly Language Programming

SHORT—This operator is used to tell the assembler that only a 1-byte


displacement is needed to code a Jump instruction. The destination must be in
the range of –128 to +127 bytes from the address of the instruction after jump.
JMP SHORT NEARBY_LABEL
TYPE—This 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. For a byte-type variable, the assembler will give a value of 1. For a
word type variable, the assembler will give a value of 2 etc.
The TYPE operator can be used in an instruction such as
ADD BX, TYPE WORD_ARRAY, where we want to increment BX to point to the
next word in an array of words.

Note: A Large Set of Programs using debugger and the Macro-Assemblers will be
discussed in the class. Some sample programs are listed below.

To Add two 16-bit numbers(Without Carry)

DATA SEGMENT

ONE DW 1234H
TWO DW 5678H
RESULT DW ?

DATA ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA

START:MOV AX,DATA
MOV DS,AX
MOV AX,ONE
ADD AX,TWO
MOV RESULT,AX
INT 3

CODE ENDS
END START

Program to find the largest of 5 bytes.


data segment
arr db 09,02,99,02,05
count dw 05h
lar db ?
data ends
code segment
assume cs:code,ds:data
start:mov ax,data
mov ds,ax

56
Chapter 2 Assembly Language Programming

mov si,offset[arr]
mov cx,count
dec cx
mov al,[si]
up: inc si
cmp al,[si]
jnc down1
mov al,[si]
down1:loop up
mov lar,al
int 3
code ends
end start

To Sort an array in ascending order (Using Bubble Sorting Method)


data segment
arr db 5, 4, 3, 1, 2
count dw 05
data ends
code segment
assume cs:code, ds:data
start:mov ax,data
mov ds,ax
mov cx,count
dec cx
up2:mov dx,cx
mov bx,0000h
up1:mov al,arr[bx]
cmp al,arr[bx+1]
jbe down
xchg al,arr[bx+1]
mov arr[bx],al
down:inc bx
loop up1
mov cx,dx
loop up2
int 3h
code ends
end start

To Copy a String from one set of locations to another


data segment
testmsg db 'Mekelle Institute of Technology'
len dw 30
data ends
dst segment
dest db 30 dup(0)
dst ends
code segment
assume cs:code,ds:data,es:dst

57
Chapter 2 Assembly Language Programming

start:mov ax,data
mov ds,ax
mov ax,dst
mov es,ax
lea si,testmsg
lea di,dest
mov cx,len
cld
rep movsb
mov ah,4ch
int 21h
code ends
end start

58

You might also like