You are on page 1of 28

Chapter 3(A)

8086/8088 CPU Architecture and Instruction Set


The Intel 8086 microprocessor was the most advanced microprocessor when it was released.
This 16 bit microprocessor was implemented in advanced N-channel, depletion load, silicon
gate (NMOS) technology and is available in three clock rates: 5, 8 and 10 MHz. The
designers of this processor made numerous advances in processor technology such as
pipelining and caching. The 8086 is designed for operation in single processor and
multiprocessor configurations. Multiprocessor configuration systems use more than one 8086
microprocessor to achieve higher performance levels. The 8086 microprocessor can directly
address 1 M byte of memory.

The 8086 microprocessor was a 16 bit processor. By this term what we mean is that firstly it
has a 16 bit wide data bus which, effectively means that it can operate on 16 bit of data from
memory and ports. Secondly, the ALU and registers were designed to work on 16 bits of
data.

Since the 8086 microprocessor has a 20 bit wide address bus, it can effectively address a
maximum of 220 or 1048576 memory locations where each of these locations references to a
byte wide memory register. Therefore, we can say that the 8086 can directly access 1 M byte
of memory.

One thing about the 8086 operation that we have to always remember is that when the first
byte of a 16 bit data is at a even memory address, the 8086 can read (or write) 16 bits (2
bytes) in one cycle. However, in the other case, that is the first byte of a 16 bit data is at an
odd memory location, the 8086 CPU will read (or write) the first byte in one bus cycle
followed by the second byte in the next bus cycle. This effectively cumulates to the fact that
must be always remembered:
1. A 16 bit data will be read in one cycle if located at an even memory address.
2. A 16 bit data will be read in two cycles if located at an odd memory location.

With the 8086 processor, Intel also released the 8088 microprocessor. The 8088 is a scaled
down version of the 8086 that is internally a 16 bit microprocessor having the same ALU and
register file as the 8086 microprocessor. It also has the same 20 bit address bus but the
difference between the 8086 and 8088 lies in the width of the external data bus. The 8088 has
an 8 bit data bus thereby enabling it to read or write only one byte of data from memory or
I/O ports.

The 8086/8088 CPU Internal Architecture


The detailed architecture of the microprocessor is to be discussed before its programming and
cycling time is to be discussed. So for the discussion of the internal architecture let’s start
with the block diagram of the microprocessor. Following figure shows the block diagram of
the 8086 microprocessor.

1
Since the 8086 followed the 8085, designers pressed for the need for processor speed up. By
speedup, we means to effectively increase the execution speed of a microprocessor. General
terminology for increase in speed (or execution rate) of a microprocessor is called speedup.
The Intel 8086 used advanced processing techniques to speed up execution. For this, the 8086
was internally divided into two functional units:
1. THE EXECUTION UNIT (EU)
2. THE BUS INTERFACE UNIT (BIU)
Both, these units are designed to work simultaneously. It is therefore, obvious that the
processing time required for an instruction will be reduced in comparison to a processor
having only a single unit working at a time. The reason for this is in the division of work
between the two, where, the BIU is designed to function as the external interface of the
processor. Effectively thus the BIU generates addresses and sends them on the address bus
and then reads (or writes) data from memory (and ports) through the data bus. Therefore the
BIU is the interface for the external buses to the EU. In short the BIU is the interface of the
EU to the outside world.

The Execution unit of the 8086 handles all controlling functions such as telling the BIU
where to fetch instructions (or data) from, where to write data to, and does the instruction
decoding as well as does all of the instruction execution.

The division of the 8086 architecture into these two units can be easily seen in the above
figure. Now we shall consider these two units in detail.

2
THE EXECUTION UNIT

Observing the figure for the architecture it can be seen that the 8086 execution unit may be
divided into the following parts:
(a) Instruction Decoder and Control Subsystem
(b) Arithmetic Logic Unit (ALU)
(c) FLAG Register
(d) General Purpose Registers
(e) Index and Pointer Registers

Instruction Decoder and Control Subsystem

The EU contains the instruction decoder which translates the received instruction from the
BIU and performs the necessary operations. The instruction decoder and the control system
perform the proper sequencing and release the corresponding synchronization signals for the
proper operation of the microprocessor to achieve the task specified by the instruction being
decoded.

Arithmetic Logic Unit (ALU)

A 16 bit ALU which can perform addition, subtraction, multiplication, division and logical
operations such as AND, OR, XOR, NOT is present in the EU. The 8086 ALU can be made
to work on 16 bit or 8 bit data depending on the instruction. On completing the task the ALU
sets the corresponding flags such as zero flag, carry flag etc., of the flag register.
15 14 13 12 11 10 9 b 7 6 b 4 3 2 1 0
X X X X OF DF IF TF SF ZF X AF X PF X CF
OF — Overflow flag TF — Trap flag AF — Auxiliary carry flag
DF — Direction flag SF — Sign flag PF — Parity flag
IF — Interrupt flag ZF — Zero flag CF — Carry flag
8086/8088 Flag register
FLAG Register

The 8086/8088 flag register is shown in above figure. The 8086 has a 16 bit flag register
which contain 9 active flags. These 9 active flags can be divided into two types.
(a) Conditional flags: Conditional flags are set or reset on the basis of the result generated
from the ALU. Conditional flags are also called status flags.
(b) Control flags: The 8086 contains three control flags which are used for controlling the
microprocessor. These flags are set or reset with the help of instructions that are put in
a program and are used to control program flow.
Specifically, we shall now first discuss the respective flags.
(1) Carry Flag: This conditional flag is set when a carry is generated in the ALU as shown
by the example given below.
e.g., ADD BA2FH and A43BH
Sol. 1011101000101111 (BA2FH)
1010010000111011 (A43BH)
(1) 0101111001101010 (5E6AH)

carry

3
Thus carry flag = 1 [Carry flag is set to shown the carry generated]
In the above operation we find that after two 16 bit numbers are added their sum is 17
bits wide. This excess bit which cannot be contained in a 16 bit register or memory
location is used to set the carry flag thereby can be used by a programmer to check the
state of a result. In 8 bits addition the carry flag is set if the result is in 9 bits.
(2) Auxiliary Carry Flag: This flag is set when a carry is generated from the lower nibble
when data being operated is 8 bit wide.

Carry 0001 110


Byte1 1010 1101 (ADH)
Byte2 0100 0110 (46H)
Sum 1111 0011 (F9H)
Here in this addition operation there is a carry from lower nibble to upper nibble. So the
auxiliary carry flag is set in this particular case. The auxiliary carry flag is used during
arithmetic operations on BCD numbers.
(3) Zero Flag: This flag is set when the result of the operation is zero. A zero would set the
zero flag while a non-zero result will reset the zero flag.
(4) Sign Flag: The sign flag is set when the MSB of the result is one. This flag is used when
performing arithmetic operations on signed numbers.
(5) Overflow Flag: This flag is set when there is an overflow. This flag has importance when
dealing with the signed numbers. For example when two n bit signed numbers are added
and there is a carry generated in the (n - 2)th bit (we count bits from 0 to n-1 so MSB has
(n-1)th position) then an overflow is said to have occurred.
Carry from 6th bit
Carry 1111 011
Byte1 0110 1001 (69H)
Byte2 0101 1011 (5BH)
Sum 1100 0100 (-79H)

Here the MSB is used for the sign. What we are doing is we are adding two positive
numbers but the result comes to be negative number. This is because there is a carry from
the 6th bit (MSB is at 7th position for an 8 bit number) and it is added to the sign bit which
generates the wrong result. Here the carry from data bit at 6th position is added to the sign
bit at MSB location, which generate the wrong result.

This carry from the 6th bit location sets the overflow flag so that a programmer can check
the overflow flag and thereby be informed that the result is invalid (wrong). A
programmer can then initiate necessary steps to correct the results.
(6) Parity Flag: Parity flag is set when the ALU output has even parity and reset when
the ALU output has odd parity.
(7) Trap Flag: Used for single stepping through a program.
(8) Interrupt Flag: When the interrupt flag is set a program can be interrupted for
other more important operations. When it is reset the program execution cannot be
interrupted. (Refer to Section on Interrupts)
(9) Direction Flag: This is used with string operation.

Among the above flags 1 to 6 are conditional flags and flags 7 to 9 are control flags.

4
General Purpose Registers

The EU has four 16 bit general purpose register called the AX, BX, CX and DX Registers.
The AX register is also called the Accumulator and is one of the most important registers as
you shall read on later. When the 8086 ALU is programmed to work on 8 bit data then these
registers can be divided as follows
8 bit 8 bit
AX AH AL
BX BH BL
CX CH CL
DX DH DL

16 bit
The 8086 Registers

These 8 registers can be individually used to store 8 bit data. For 8 bit operations AL register
is the accumulator.

The Accumulator is a very important register as it has many features that others do not have.
The accumulator will be studied in great detail when we discuss the 8086 instructions.

The other register BX also called base register is also used in addressing purpose. The register
CX also called counter register is used as counting register for some instructions like LOOP
and REP. The register DX is also called as data register and is also used for some special
purpose.

There are several advantages of using internal registers for data storage:
(1) Since the CPU data transfer speed is generally higher than memory, the data transfer
is faster when during registers to ALU than memory to ALU.
(2) Secondly, since data is already in the EU (i.e., in these registers) this data can be used
faster than data from memory by the ALU.

Pointer and Index Registers

In addition to the four 16 bit general purpose registers (AX, BX, CX and DX) the execution
unit contains three other registers collectively called the Index and pointer registers. These
registers are all of 16 bits.

These registers include SI (Source index), DI (Destination index), BP (Base pointer) and SP
registers. SI, DI and BP can be used for temporary storage of data. They can only be used to
store 16 bit data unlike the General purpose registers which can be used to store 16 bit data as
well as 8 bit data. Though these registers can be programmed for data storage but they are
actually designed to be used to store the offset address of a data byte (or word) in the data
segment. BP is actually used when passing argument to procedures (functions).

The actual address will be calculated by adding the contents of SI (or DI) to the segment base
so as to produce the effective address of the data byte (or word) in the data segment.

5
BUS INTERFACE UNIT (BIU)

The bus interface unit can be divided into the following units
1. Instruction Queue
2. Segment Registers
3. Instruction Pointer
4. Bus control and address generator
These functional parts can be very clearly seen in the figure for architecture.

The Queue

The 8086 microprocessor used a method called Pipelining for speed up. This is very clearly
demonstrated in the following figure. The instruction queue of the 8086 is a six byte first in
first out (FIFO) register and can be understood as a cache memory. The 8088 on the other
hand has a four byte queue.

When the EU is executing or decoding an instruction which doesn't require the use of external
buses or the segment registers, the BIU can be thought of as being idle. Since the 8086 BIU is
independently functional the BIU fetches the next instruction bytes for the EU and stores
them in the queue. Now when the EU becomes free it can directly access (read) the instruction
from the queue (which in obviously faster when compared to the 8085 processor). It is thus
observed that the 8086 can perform two operations at the same time that is a memory read (of
instruction bytes) and an execution whereas the 8085 can only do one of the above. Thus it is
obvious that the 8086 was much faster. This is demonstrated in the above figure. In the above
figure during time intervals t2 and t3, the 8086/8088 is doing two operations, one by the BIU
and one by the EU. This is faster compared to sequential execution where one operation is
performed after the other.

Segment Registers

Another new concept that was introduced in the 8086 was memory segmentation. Memory
segmentation allowed the 8086 microprocessor to be able to access only four 64 K byte seg-
ments within its 1 M byte memory range at any given time. These four segments are defined
by the data values stored in the four segments, registers, which are named as follows:
1. CS: Code segment Register
2. SS: Stack segment Register
3. DS: Data segment Register
4. ES: Extra Data segment Register.
The use of these registers is discussed in more detail in the topic memory segmentation.

6
By default the 8086 assumes that the code (or instructions) will be fetched from the memory
segment addressed by the CS register value. Similarly, the 8086 by default uses the DS regis-
ter to address the memory segment that shall hold data bytes to be used by the program and
the SS register to address the memory segment that shall be used as stack memory.

Therefore, the default segment registers usage is shown below with the registers that shall
contain the offset address
Segment Memory Default offset
register segment register
CS Code IP
DS Data BX, SI
SS Stack SP, BP
ES Extra DI and segment
override

Instruction Pointer (IP)

The instruction pointer stores the offset of the physical address (due to memory segmentation) in the
segment of memory as defined by the segment registers. This, in short, means that the upper 16 bits of
the 20 bit address is stored in the segment register while the offset in the memory segment is stored in
the IP or the pointer and index registers.

Bus Control and Address Generation

The bus control and address generation logic subunit is one which handles the external bus as well as
calculates the effective address from where the instructions has to be fetched.

The address generation circuit is basically an adder where the content of the segment register and the
offset (pointer) registers are added to generate the actual physical address. The segment register is
always appended with four zeros (or multiplied by 10H) before being put in the adder. This is because
segments always start with address exactly divisible by 16 (10H) or at the paragraph boundary. The
output of the adder is the effective memory address or the physical address.
Now consider the following data in segment and offset registers.
3492H Segment Register
564AH Offset Register
The physical address is calculated as
Segment reg. * 10H + Offset reg. = physical memory address

Sequential Memory Access


Designers of computer systems generally use two types of memory organization. These are :
(1) Linear Addressing or organization.
(2) Segmented Addressing or organization.

Linear Addressing

The early microprocessors were organized to use the linearly addressed memory organization.
In linear addressing, the whole system memory is available to the processor as one linear

7
array. This was used in the earlier 8085 processor and is shown in following figure. In the
8085 the instruction pointer (IP) known as program counter (PC) was 16 bit wide which was
sufficient for the address of the memory location as the 8085 had a 16 bit address bus.

Segmented Addressing

Segmented memory addressing on the other hand divides the memory into many segments.
For example, the 1 MB memory is divided into smaller segments of 64 KB. This is because
the memory with in the segment is addressed by the pointer registers and they all are of 16 bit
wide (and so 216 bytes = 64 Kilobytes). Each of these segments can be considered as a linear
memory space as discussed above.

8086/8088 microprocessor is designed to have the segment address always at paragraph


boundary (exactly divisible by 10H). So among the 20 bit address the last 4 bits are always
zero. Since the last four bits are always zero we don't need to store the last 4 bits. (In other
way the 20 bit address can be represented by five hex digits and among the five digits the last
hex digits is always zero) Each of these segments is addressed by a segment register which
are of 16 bits. So the significant 16 bit address is stored in the segment registers. Since the
segment register is 16 bit wide and the memory needs 20 bits for an address the 8086 appends
four zero bits to the segment register to obtain the segment address during memory read or
memory write. Therefore, to address the segment 34920H by the DS register, the DS must
contain 3492H. But during the memory read or write BIU appends the last four zeros to make
the actual segment address.

Thus if a segment registers has any arbitrary value XXXX H the 8086 assumes it points to
XXXX 0 H (or a 20 bit address where XXXX is the segment registers value). This is known
as the segment base address. Effectively this means that the segment registers is used to refer-
ence to the zeroth address of the segment. So to address within the segment we need other

8
register to indicate the offset of the memory location within the segment. When the offset
address stored in another register is added to the (segment) base address a valid 20 bit address
is produced. As all the address (offset) registers are of 16bit size they can address 64KB at
most within the segment.
Let DS has 3492H and SI has 24ABH then the actual physical address is calculated as:
3492H*10H=34920H
34920H Base Address
+ 24ABH Offset Address
36dCBH Physical Address
The register that is added is said to contain the offset address. This is very clearly understood
as shown in following figure.

In 8086/8088 there are four segment registers so microprocessor can address total of four
segments. Any executable program of 8086 microprocessor can have four segments and these
four segments can be addressed by four segment registers. So the executable program can use
up to 64KB x 4 (256KB) of memory at one time.

9
However the executable programs may not use the entire 64KB segment. In other words the
segment that executable programs use can be smaller than 64KB depending upon the
requirement. For example if a program requires only three data variables each of 16 bits, then
the data segment of that program is of 6 bytes.

The segment registers need not be same all the time during the run time. By changing these
segment registers values during the processor operation we can utilize different spaces in the
1 MB memory. Some time all the four segment registers can address same segment or some
time the segments can overlap. A typical segmented memory space of the 8086 is illustrated
in above figure.

As discussed earlier the addresses within a segment can range from 0000H to FFFFH. The
address within the segment is called offset or logical address. This is because the size of the
register holding the offset address is 16 bit and hence the range of address is from 0000H to
FFFFH.

Now the physical address is the address that is actually sent on the address bus (that is it is 20
bits wide). The offset or logical address is the offset from the location zero of a segment. The
segment address is the location pointed by the base address or the segment register.

Advantage of Memory Segmentation

Though the memory segmentation is slightly complex but as we go on learning about it we


shall find out about its advantages. The first advantage that memory segmentation has is that
only 16 bit registers are required both to the store segment base address as well as offset
address. This makes the internal circuitry easier to build as it removes the requirement for 20
bits register in case the linear addressing method is used.

The second advantage is the ability to reallocate. For example in a normal computer system
time sharing process is used. Time sharing involves allocating a fixed amount of time for
programs of different users. However, memory segmentation is a boon for time shared
systems as all user programs can be loaded into memory. The 8086 can then be made to work
on a time sharing basis on each of this program by just reloading the segment address of each
of these programs in the segment registers. Thus segmentation allows the programmer to
separately use each of the program loaded in memory by just reloading the 8086 segment
registers.

Addressing Modes
An addressing mode is a way of specifying the operands in any instruction. An operand
address provides a source of data for an instruction to process. Some instructions, such as
STC and RET, do not require an operand, whereas other instructions may have one or two
operands. Where there are two operands, the first operand is the destination, which contains
data in a register or in memory, and which is to be processed. The second operand is the
source, which contains either the data to be delivered (immediate) or the address (in memory
or of a register) of the data. The source data for most instructions is unchanged by the
operation. The three basic modes of addressing are register, immediate, and memory; memory
addressing consists of six types, for eight modes in all.
10
1. Register Addressing

For this mode, a register provides the name of any of the 8- or 16-bit registers. Depending
on the instruction, the register may appear in the first operand, the second operand, or
both, as the following examples illustrate:
MOV DX,WORD_MEM ;Register in first operand
MOV WORD_MEM,CX ;Register in second operand
Because processing data between registers involves no reference to memory, it is the
fastest type of operation.

2. Immediate Addressing

An immediate operand contains a constant value or an expression. Here are some


examples of valid immediate constants:
Hexadecimal: 0148H
Decimal: 328 (which the assembler converts to 0148H)
Binary: lO1OO10OOB; (which converts to 0148H)
For many instructions with two operands, the first operand may be a register or memory
location, and the second may be an immediate constant. The destination field (first
operand) defines the length of the data. Here are some examples:
BVTE_VAL DB 150 ;define byte
WORD_VAL DW 3 00 ;word
DBWD_VAL DD 0 ;double word

...
SUB BYTE_VAL,50 ;Immediate to memory (byte)
MOV WORD_VAL,40H ;Immediate in memory (word)
MOV DBWD_VAL,0 ;Immediate in memory (doubeword)
MOV AX,0245H ;Immediate to resister (word)
The instruction in the last example moves the immediate constant 0245H to AX. The 3-
byle object code is B84502, where B8 means “move an immediate value to AX” and the
following two bytes contain the value itself (4502H, in reverse byte sequence).

The use of an immediate operand provides faster processing than defining a numeric
constant in the data segment and referencing it in an operand.

The length of an immediate constant cannot exceed the length defined by the first
operand. In the following invalid example, the immediate operand is two bytes, but AL is
only one byte:
MOV AL,0245H ;Invalid immediate length
However, if an immediate operand is shorter than a receiving operand, as in
ADD AX,48H ;Valid immediate length
the assembler expand the immediate operand to two bytes. 0048H. and stores it in object
code as 4800H.

3. Direct Memory Addressing

In this format, one of the operands references a memory location and the other operand
references a register. (The only instructions that allow both operands to address memory
directly are MOVS and CMPS.) DS is the default segment register for addressing data in
memory as DS:offset. Here are some examples:
11
ADD BYTE_VAL,DL ;Add register to memory (byte) MOV
BX,WORD_VAL ;Move memory to register (word)

4. Direct-Offset Addressing

This addressing mode, a variation of direct addressing, uses arithmetic operators to


modify an address. The following examples use these definitions of tables::
BYTE_TBL DB 12, 15, 16, 22, ... ;Table of bytes
WORD_TBL DB 163, 227, 485, ... ;Table of words
Byte Operations: These instructions access bytes from BYTE_TBL:
MOV CL,BYTE_TBL[2] ;Get byte from BYTEJTBL
MOV CL,BYTE_TBL+2 ;Same operation
The first MOV uses an arithmetic operator to access the third byte (16) from
BYTE_TBL. (BYTE_TBL[0] is the first byte, BYTE_TBL[1] the second, and
BYTE_TBL[2] the third.) The second MOV uses a plus (+) operator for exactly the same
effect.
Word Operations: These instructions access words from WORD_TBL:
MOV CX, WORD_TBL [4] ;Get word from WORD_TBL
MOV CX,W0RD_TBL+4 ;Same operation
The MOVs access the third word of WORD_TBL. (WORD_TBL[0] is the first word,
WORD_TBL[2] the second, and WORD_TBL[4] the third.)

5. Indirect Memory Addressing

Indirect addressing takes advantage of the computer's capability for segment:offset ad-
dressing. The registers used for this purpose are base registers (BX and BP) and index reg-
isters (DI and SI), coded within square brackets, which indicate a reference to memory.

An indirect address such as [DI] tells the assembler that the memory address to use will
be in DI when the program subsequently executes. BX, DI, and SI are associated with DS
as DS:BX, DS:DI, and DS:SI, for processing data in the data segment. BP is associated
with SS as SS:BP, for handling data in the stack.

When the first operand contains an indirect address, the second operand references a
register or immediate value; when the second operand contains an indirect address, the
first operand references a register. Note that a reference in square brackets to BP, BX, DI,
or SI implies an indirect operand, and the processor treats the contents of the register as
an offset address when the program is executing.

In the following example, LEA first initializes BX with the offset address of
DATA_VAL. MOV then uses the address now in BX to store CL in the memory location
to which it points, in this case, DATA_VAL:
DATA_VAL DB 50 ;Define byte
...
LEA BX,DATA_VAL ;Load BX with offset
MOV [BX],CL ;Move CL to DATA_VAL
The effect of the two MOVs is the same as coding MOV DATA_VAL,25. Here are a few
more examples of indirect operands:
ADD CL,[BX] ;2nd operand = DS:BX
MOV BYTE PTR [DI],25 ;1st operand = DS:DI
ADD [BP],CL ;lst operand = SS:BP

12
The next example uses an absolute value for an offset:
MOV CX,DS:[38B0H] ;Word in memory at offset 38B0H

6. Base Displacement Addressing

This addressing mode also uses base registers (BX and BP) and index registers (DI and
SI), but combined with a displacement (a number or offset value) to form an effective
address. The following MOV instruction moves zero to a location two bytes immediately
following the start of DATA_TBL:
DATA_TBL DB 365 DUP(?) ;Define bytes
...
LEA BX,DATA_TBL ;Load BX with offset
MOV BYTE PTR [BX+2],0 ;Move 0 to DATA_TBL+2
And here are some additional examples:
ADD CL,[DI+12] ;DI offset plus 12 (or 12[DI])
SUB DATA_TBL[SI] ,25 ;SI contains offset
MOV DATA_TBL[DI],DL ;DI contains offset

7. Base-Index Addressing

This addressing mode combines a base register (BX or BP) with an index register (DI or
SI) to form an effective address; for example, [BX+DI] means the address in BX plus the
address in DI. A common use for this mode is in addressing a 2-dimensional array,
where, say, BX references the row and SI the column. Here are some examples:
MOV AX,[BX+SI] ;Move word from memory
ADD [BX+DI],CL ;Add byte to memory

8. Base-Index with Displacement Addressing

This addressing mode, a variation on base-index, combines a base register, an index


register, and a displacement to form an effective address. Here are some examples:
MOV AX,[BX+DI+10] ;or 10[BX+DI]
MOV CL,DATA_TBL[BX+DI] ;or [BX+DI+DATA_TBL]

The Segment Override Prefix

The processor automatically selects the appropriate segment when addressing: CS:IP for
fetching an instruction, DS:offset for accessing data in memory, and SS:SP for accessing the
stack. There are occasions, especially for large programs, when you have to handle data that
is subject to another segment register, such as the ES. An example would be a large table of
data loaded from external storage into memory in a separate segment of the program.

You can use any instruction to process the data in the other segment, but you must identify
the appropriate segment register. Let's say that the address of the other segment is in ES, and
BX contains an offset address within that segment. The requirement is to move two bytes (a
word) from that location to DX.
MOV DX,ES:[BX] ;Move to DX from ES:[BX]
The coding of "ES:" indicates an override operator that means "Replace the normal use of the
DS segment register with that of ES." The next example moves a byte value from CL into this
other segment, at an offset formed by the value in SI plus 36.

13
MOV ES:[SI+36],CL ;Move to ES:[SI+36] from CL
The assembler generates object code with the override operator inserted as a 1-byte prefix
(26H) immediately preceding the instruction, just as if you had coded the two instructions as
ES: MOV DX,[BX] ;Move to DX from ES :[BX]
ES: MOV [SI+36],CL ;Move to ES:[SI+36] from CL

Near and Far Addresses

An address in a program may be near or far. A near address consists of only the 16-bit offset
portion of an address. An instruction that references a near address assumes the current
segment—namely, DS for data segment and CS for code segment.

A far address consists of both the segment and offset portions in the form of 32-bit segment:
offset. An instruction may reference a far address from within the current segment or in
another segment.

Almost all assembly programming in real mode makes use of near addresses, which the
assembler generates unless instructed otherwise. Large programs that consist of many
segments would require far addresses as do programs defined with the Flat memory model.

The Instruction Set


The following is a list of the symbolic instructions for the 8086/8088 processors, arranged by
category. Among these instructions some are rarely used.

ARITMETIC

ADD: Add Binary Numbers


Adds binary values from memory, register, or immediate to a register, or adds values in a
register or immediate to memory. Values may be bytes or words.
Flags: Affects AF, CF, OF, PF, SF, and ZF.
Source code: ADD register/memory,register/memory/immediate

ADC: Add with Carry


It is typically used in multiword binary addition to carry an overflowed 1-bit into the next
stage of arithmetic. ADC adds the contents of the Carry Flag (0/1) to operand 1, and then
adds operand 2 to operand 1, just like ADD. (See also SBB.)
Flags: Affects AF, CF, OF, PF, SF, and ZF.
Source code: ADC register/memory,register/memory/immediate

SUB: Subtract Binary Values


It subtracts binary values in a register, memory, or immediate from a register, or subtracts val-
ues in a register or immediate from memory. Values may be byte or word. (See also SBB.)
Flags: Affects AF, CF, OF, PF, SF, and ZF.
Source code: SUB register/memory,register/memory/immediate

SBB: Subtract with Borrow

14
It is typically used in multiword binary subtraction to carry an overflowed 1 bit into the next
stage of arithmetic. SBB first subtracts the contents of the CF (0/1) from operand1 and then
subtracts operand2 from operand1, just like SUB. (See also ADC.)
Flags: Affects AF, CF, OF, PF, SF, and ZF.
Source code: SBB register/memory,register/memory/immediate

INC: Increment by 1
Increments by 1 a byte, or word in a register or memory and treats the value as an unsigned
integer, coded, for example, as INC CX. (See also DEC.)
Flags: Affects AF, OF, PF, SF, and ZF (but not CF).
Source code: INC register/memory

DEC: Decrement by 1
Decrements 1 from a byte or word in a register or memory and treats the value as an unsigned
integer. (See also INC.)
Flags: Affects AF, OF, PF, SF, and ZF.
Source code: DEC register/memory

MUL: Unsigned Multiply


The instruction multiplies an unsigned multiplicand by an unsigned multiplier. MUL treats a
leftmost 1-bit as a data bit, not a negative sign. The operation assumes the multiplicand is in
AL or AX and takes its size from that of the multiplier. (See also IMUL.) Here are the
multiply operations according to the size of the multiplier:

Size Multiplicand Multiplier Product Example


8-bit AL 8-bit reg/memory AX MUL BH
16-bit AX 16-bit reg/memory DX:AX MUL CX
Flags: Affects CF and OF. (AF, PF, SF, and ZF are undefined.)
Source code: MUL register/memory

IMUL: Signed (Integer) Multiply


The instruction multiplies a signed multiplicand by a signed multiplier. The operation treats
the leftmost bit as the sign (0 = positive, 1 = negative). The operation assumes the
multiplicand is in AL or AX, and takes its size from that of the multiplier. (See also MUL.)
Here are the operations according to size:

Size Multiplicand Multiplier Product Example


8-bit AL 8-bit reg/memory AX IMUL BH
16-bit AX 16-bit reg/memory DX:AX IMUL CX
The other three formats reference any 16- or 32-bit general-purpose register; lengths of data
items must be the same.
Flags: Affects CF and OF. (AF, PF, SF, and ZF are undefined.)
Source code: IMUL register/memory

DIV: Unsigned Divide


The instruction divides an unsigned dividend in operand1 by an unsigned divisor. DIV treats a
leftmost 1-bit as a data bit, not a minus sign. Division by zero causes a zero-divide interrupt.
(See also IDIV.) Here are the divide operations according to size of dividend:

15
Size Dividend Divisor Quotient Remainder Example
16-bit AX 8-bit reg/memory AL AH DIV BH
32-bit DX:AX 16-bit reg/memory AX DX DIV CX
Flags: Affects AF, CF, OF, PF, SF, and ZF. (All undefined.)
Source code: DIV register/memory

IDIV: Signed (Integer) Divide


The instruction divides a signed dividend by a signed divisor. IDIV treats a leftmost bit as a
sign (0 = positive, 1 = negative). Division by zero causes a zero-divide interrupt. (See CBW
and CWD to extend the length of a signed dividend, and see also DIV.) Here are the divide
operations according to the size of the dividend:

Size Dividend Divisor Quotient Remainder Example


16-bit AX 8-bit reg/memory AL AH IDIV BH
32-bit DX:AX 16-bit reg/memory AX DX IDIV CX
Flags: Affects AF, CF, OF, PF, SF, and ZF.
Source code: IDIV register/memory

NEG: Negate
The instruction reverses a binary value from positive to negative or from negative to positive.
NEG provides the two's complement of the specified operand by subtracting the operand from
zero and adding 1. Operands can be a byte or word in a register or memory. (See also NOT.)
Flags: Affects AF, CF, OF, PF, SF, and ZF.
Source code: NEG register/memory

ASCII-BCD CONVERSION (Not frequently used)

DAA: Decimal Adjust After Addition


It corrects the result in AL after an ADD or ADC has added two packed BCD items. If the
value of the rightmost four bits is greater than 9, or if the Auxiliary Flag is 1, DAA adds 6 to
AL and sets the AF. Next, if the value in AL is greater than 99H, or if the Carry Flag is 1,
DAA adds 60H to AL and sets the CF. Otherwise, the AF and CF are cleared. AL now
contains a correct two-digit packed decimal result. (See also DAS.)
Flags: Affects AF, CF, PF, SF, and ZF (OF is undefined.)
Source code: DAA (no operand)

DAS: Decimal Adjust After Subtraction


It corrects the result in AL after a SUB or SBB has subtracted two packed BCD items. If the
value of the rightmost four bits is greater than 9, DAS subtracts 60H from AL and sets the
Carry Flag. Otherwise, it clears the Auxiliary and Carry Flags. AL now contains a correct two-
digit packed decimal result. (See also DAA.)
Flags: Affects AF, CF, PF, SF, and ZF (OF is undefined.)
Source code: DAS (no operand)

AAA: ASCII Adjust After Addition.


The instruction corrects the sum (after an ADD) in AL of two ASCII bytes. If the value of the
rightmost four bits of AL is greater than 9, or if the AF is set to 1, AAA adds 1 to AH, adds 6
to AL, and sets the AF and CF. Otherwise, the AF and CF are cleared. AAA always clears the
leftmost four bits of AL.

16
Flags: Affects AF and CF (OF, PF, SF, and ZF are undefined.)
Source code: AAA (no operand)

AAS: ASCII Adjust After Subtraction


The instruction adjusts the difference in AL (after a SUB) of two ASCII bytes. If the value
of the rightmost four bits is greater than 9, or if the Carry Flag is 1, AAS subtracts 6 from
AL, subtracts 1 from AH, and sets the AF and CF. Otherwise, the AF and CF are cleared.
AAS always clears the leftmost four bits of AL.
Flags: Affects AF and CF. (OF, PF, SF, and ZF are undefined.)
Source code: AAS (no operand)

AAD: Adjust (BCD to Binary) Before Division


The instruction adjusts an unpacked BCD value (dividend) in AX prior to division. AAD
multiplies AH by 10, adds the product to AL, and clears AH. The resulting binary value in
AX is now equivalent to the original unpacked BCD value and is ready for a binary divide
operation.
Flags: Affects PF, SF and ZF (AF, CF, and OF are undefined.)
Source code: AAD (no operand)

AAM: Adjust (BCD) After Multiplication


The instruction adjusts the product in AL generated by multiplying two unpacked BCD
digits. AAM divides AL by 10 and stores the quotient in AH and the remainder in AL.
Flags: Affects PF, SF, and ZF (AF, CF, and OF are undefined.)
Source code: AAM (no operand)

LOGICAL OPERATIONS

AND: Logical AND


Performs a logical AND operation on bits of two operands. Both operands are bytes or
words, which AND matches bit for bit. For each pair of matched bits that are 1, the 1-bit in
the first operand is set to 1; otherwise, the bit is cleared. (See also OR, XOR, and TEST.)
Flags: Affects CF (0), OF (0), PF, SF, and ZF (AF is undefined.)
Source code: AND register/memory,register/memory/immediate

OR: Logical OR
The instruction performs a logical OR operation on bits of two operands. Both operands are
bytes or words, which OR matches bit for bit. For each pair of matched bits, if either or both
are 1, the bit in the first operand is set to 1; otherwise the bit is unchanged. (See also AND
and XOR.)
Flags: Affects CF (0), OF (0), PF, SF, and ZF (AF is undefined.)
Source code: OR register/memory,register/memory/immediate

NOT: Logical NOT


It changes 0-bits to 1 -bits and vice versa. The operand is a byte or word in a register or
memory. (See also NEG.)
Flags: Affects none.
Source code: NOT register/memory

17
XOR: Exclusive OR
The instruction performs a logical exclusive OR on bits of two operands. Both operands are
bytes or words, which XOR matches bit for bit. For each pair matched bits, if both are the
same, the bit in the first operand is cleared to 0; if the matched bits are different the bit in the
first operand is set to 1. (See also AND and OR.)
Flags: Affects CF (0), OF (0), PF, SF, and ZF (AF is undefined.)
Source code: XOR register/memory,register/memory/immediate

BIT SHIFTING/ROTATING

ROL/ROR: Rotate Left or Rotate Right


These instructions rotate bits left or right in a byte or word in a register or memory. The
operand may be an immediate constant or a reference to CL. On the 8088/86, the constant
may be only 1; a larger rotate must be in CL. For ROL, the leftmost bit enters bit 0 of the
destination; all other bits rotate left. For ROR, bit 0 enters the leftmost bit of the destination;
all other bits rotate right. (See also RCL and RCR.) The rotated bit also enters the Carry Flag.
Flags: Affects CF and OF.
Source code: ROL/ROR register/memory,CL/immediate

RCL/RCR: Rotate Left through Carry/Rotate Right through Carry


These instructions rotate bits through the Carry Flag. The operation rotates bits left or right in
a byte or word in a register or memory. The operand may be an immediate constant or a ref-
erence to CL. On the 8088/86, the constant may be only 1; a larger rotate must be in CL. For
RCL, the leftmost bit enters the Carry Flag, and the CF bit enters bit 0 of the destination; all
other bits rotate left. For RCR, bit 0 enters the Carry Flag, and the CF bit enters the leftmost
bit of the destination; all other bits rotate right. (See also ROL and ROR.)
Flags: Affects CF and OF
Source code: RCL/RCR register/memory,CL/immediate

SHL/SHR: Shift Logical Left/Shift Logical Right


These instructions shift bits left or right in a byte or word in a register or memory. The
operand may be an immediate constant or a reference to CL. On the 8088/86, the constant
may be only 1; a larger shift must be in CL. SHL and SHR are logical shifts that treat the sign
bit as a data bit.

SHL shifts bits to the left a specified number and fills 0 bits in vacated positions to the right.
SHL acts exactly like SAL. SHR shifts bits to the right a specified number and fills 0 bits to
the left. All bits shifted off are lost.
Flags: Affects CF, OF, PF, SF, and ZF. (AF is undefined.)
Source code: SHL/SHR register/memory,CL/immediate

SAL/SAR: Shift Algebraic Left/Shift Algebraic Right


Shifts bits to the left or right in a byte or word in a register or memory. The operand may be
an immediate constant or a reference to CL. On the 8088/86, the constant may be only 1; a
larger shift must be in CL.

SAL shifts bits to the left a specified number and fills 0 bits in vacated positions to the right.
SAL acts exactly like SHL. SAR is an arithmetic shift that considers the sign of the

18
referenced field. SAR shifts bits to the right a specified number and fills the sign bit (0 or 1)
to the left. All bits shifted off are lost.
Flags: Affects CF, OF, PF, SF, and ZF. (AF is undefined.)
Source code: SAL/SAR register/memory,CL/immediate

COMPARISON

CMP: Compare
The instruction compares the binary contents of two data fields. CMP internally subtracts
operand 2 from operand 1 and sets/clears flags, but does not store the result. Both operands
are byte or word. CMP may compare register, memory, or immediate to a register or may
compare register or immediate to memory. (CMP makes a numeric comparison; see CMPS
for string comparisons.) The results are the following:
CF SF ZF
operand1 < operand2 1 1 0
operand1 = operand2 0 0 1
operand1 > operand2 0 0 0
Flags: Affects AF, CF, OF, PF, SF, and ZF.
Source code: CMP register/memory,register/memory/immediate

TEST: Test Bits


It uses AND logic to test a field for a specific bit configuration, but does not change the
destination operand. Both operands are bytes or words in a register or memory; the second
operand may be immediate. The operation clears the ZF if any pair of matched bits are 1; else
it sets the ZF. After its execution, you may use a Jnn instruction to test the flags.
Flags: Clears CF and OF and affects PF, SF, and ZF. (AF is undefined.)
Source code: TEST register/memory,register/memory/immediate

CMPS/CMPSB/CMPSW: Compare String


See String operations.

SCAS/SCASB/SCASW: Scan String


See String operations

DATA TRANSFER

MOV: Move Data


It transfers data between two registers or between a register and memory, and transfers im-
mediate data to a register or memory. The referenced data defines the number of bytes (1 or
2) moved; the operands must agree in size. MOV cannot transfer between two memory
locations (use MOVS), from immediate data to segment register, or from segment register to
segment register.
Flags: Affects none.
Source code: MOV register/memory,register/memory/immediate

LDS/LES/LSS: Load Segment Register


Operand1 references any of the general, index, or pointer registers. Operand2 references two
words in memory containing an offset:segment address. The operation loads the segment

19
address in the segment register and the offset in the operand 1 register. Used for example as
LDS DI,SEG_ADDRESS.
Flags: Affects none.
Source code: LDS/LES/LSS register,memory

LEA: Load Effective Address


The instruction loads a near (offset) address into a register.
Flags: Affects none.
Source code: LEA register,memory

IN: Input Byte or Word


The instruction transfers from an input port a byte to AL or word to AX. Code the port as a
fixed numeric operand (as IN AX,port#) or as a variable in DX (as IN AX,DX). Use DX if
the port number is greater than 256. (See also OUT.)
Flags: Affects none
Source code: IN AL/AX,portno/DX.

OUT: Output Byte or Word


This instruction transfers a byte from AL or word from AX to an output port. The port is a
fixed numeric operand or a variable in DX. Use DX if the port number is greater than 256.
(See also IN.)
Flags: Affects none.
Source code: Fixed port: OUT port#,AX
Variable port: OUT DX,AX

XCHG: Exchange
Exchanges data between two registers (as XCHG AH,BL) or between a register and memory
(as XCHG CX,word).
Flags: Affects none.
Source code: XCHG register/memory,register/memory

XLAT/XLATB: Translate
These instructions translate bytes into a different format, such as encrypted data. Load the
address of a translate table in BX or EBX for 32-bit size, and then load AL with a value that
is to be translated. The operation uses the AL value as an offset into the table, selects the byte
from the table, and stores it in AL. (XLATB is a synonym for XLAT.)
Flags: Affects none.
Source code: XLAT/XLATB [AL] (AL operand is optional)

MOVS/MOVSB/MOVSW: Move String


See String operations

LODS/LODSB/LODSW: Load Byte or Word String


See String operations

STOS/STOSB/STOSW: Store String


See String operations

20
FLAG OPERATIONS

CLC: Clear Carry Flag


The instruction clears the CF so that, for example, ADC does not add a 1-bit. (See also STC.)
Flags: CF (becomes 0).
Source code: CLC (no operand)

CLD: Clear Direction Flag


It clears the DF, to cause string operations such as MOVS to process from left to right. (See
also STD.)
Flags: DF (becomes 0).
Source code: CLD (no operand)

CLI: Clear Interrupt Flag


It clears the IF, to disable maskable external interrupts. (See also STI.)
Flags: IF (becomes 0).
Source code: CLI (no operand)

CMC: Complement Carry Flag


Reverses the CF bit values: 0 becomes 1 and 1 becomes 0.
Flags: CF (reversed).
Source code: CMC (no operand)

LAHF: Load AH from Flags


Loads the low-order eight bits of the Flags register into AH. (See also SAHF.)
Flags: Affects none.
Source code: LAHF (no operand)

SAHF: Store AH Contents in Flags


Stores the eight bits from AH in the low-order bits of the Flags register. (See also LAHF.)
Flags: Affects AF, CF, PF, SF, and ZF
Source code: SAHF (no operand)

STC: Set Carry Flag


It sets the CF to 1. (See CLC for clear CF.)
Flags: Sets CF.
Source code: STC (no operand)

STD: Set Direction Flag


It sets the DF to 1 to cause string operations such as MOVS to process from right to left. (See
CLD for clear DF.)
Flags: Sets DF.
Source code: STD (no operand)

STI: Set Interrupt Flag


It sets the IF to 1 to enable maskable external interrupts after execution of the next instruc-
tion. (See CLI for clear IF.)
Flags: Sets IF.

21
Source code: STI (no operand)

PUSHF: Push Flags onto Stack


See Stack operations

POPF: Pop Flags off Stack


See Stack operations

LOOPING

LOOP: Loop Until Complete


It controls the execution of a routine for a specified number of times. CX should contain a
count before starting the loop. LOOP appears at the end of the loop and decrements CX by 1.
If CX is nonzero, LOOP transfers to its operand address (a short jump), which points to the
start of the loop (adds the offset in IP); otherwise LOOP drops through to the next instruction.
Flags: Affects none.
Source code: LOOP label

LOOPE/LOOPZ: Loop While Equal/Loop While Zero


These instructions control the repetitive execution of a routine. LOOPE and LOOPZ are
similar to LOOP, except that they transfer to the operand address (a short jump) if CX is
nonzero and the Zero Flag is 1 (zero condition, set by another instruction); otherwise the
operation drops through to the next instruction. (See also LOOPNE/LOOPNZ.)
Flags: Affects none.
Source code: LOOPE/LOOPZ label

LOOPNE/LOOPNZ: Loop While Not Equal/Loop While Not Zero


These instructions control the repetitive execution of a routine. LOOPNE and LOOPNZ are
similar to LOOP, except that they transfer to the operand address (a short jump) if CX is
nonzero and the Zero Flag is 0 (nonzero condition, set by another instruction); otherwise the
operation drops through to the next instruction. (See also LOOPE/LOOPZ.)
Flags: Affects none.
Source code: LOOPNE/LOOPNZ label

REP: Repeat String


See String operation

REPE/REPZ/REPNE/REPNZ: Repeat String Conditionally


See String operation

BRANCHING

CALL: Call a Procedure (Unconditional)


The instruction calls a near or far procedure. The assembler generates a near CALL if the
called procedure is NEAR and a far CALL if the called procedure is FAR. A near CALL
pushes IP (the offset of the next instruction) onto the stack; it then loads IP with the
destination offset. A far CALL pushes CS onto the stack and loads an intersegment address
onto the stack; it then pushes IP onto the stack and loads IP with the destination offset. On

22
return, a subsequent RETN or RETF is used to reverse these steps.
Flags: Affects none.
Source code: CALL register/memory

RET: Return from a Procedure (Unconditional)


It returns the control from a procedure previously entered by a near or far CALL. The
assembler assumes a near RET if it is within a procedure labeled NEAR and assumes a far
RET if it is within a procedure labeled FAR. For near, RET moves the word at the top of the
stack to IP and increments SP by 2, for far, RET moves the words at the top of the stack to IP
and CS and increments SP by 4. RET instruction can be followed by an immediate operand
e.g. RET 6. In this case the stack pointer will be incremented by an additional six addresses
after the ip or 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.
Flags: Affects none.
Source code: RET [immediate]

INT: Interrupt (Unconditional)


Interrupts processing and transfers control to one of the 256 addresses in the Interrupt Vector
Table. INT performs the following: (1) pushes the flags onto the stack and resets the Interrupt
and Trap flags; (2) pushes CS onto the stack and places the high-order word of the interrupt
address in CS; and (3) pushes IP onto the stack and fills IP with the low-order word of the
interrupt address. IRET is used to return from the interrupt routine.
Flags: Clears IF and TF.
Source code: INT number

IRET: Interrupt Return (Unconditional)


The instruction provides a far return from an interrupt routine. IRET performs the following
procedure: (1) pops the word at the top of the stack into IP, increments SP by 2, and pops the
top of the stack into CS; (2) increments SP by 2 and pops the top of the stack into the Flags
register. This procedure undoes the steps that the interrupt originally took and performs a
return. (See also RET.)
Flags: Affects all.
Source code: IRET

JMP: Unconditional Jump (Unconditional)


The instruction causes a jump to a designated address under any condition. A JMP address may be
short (-128 to + 127 bytes), near (within + or -32K, the default), or far (to another code segment). A
short or near JMP replaces IP with a destination offset address. A far jump (such as JMP FAR PTR
label) replaces CS:IP with a new segment address.
Flags: Affects none.
Source code: JMP register/memory

Jnn: Jump on Condition


These are the group of jump instructions that test the status of various flags. If the test is true,
the operation adds the operand offset to IP and transfers control to the CS:IP address; if not
true, processing continues with the next instruction in sequence. The jump for 8086 is always
short (-128 to 127 bytes).
Flags: Affects none but uses the flag conditions.
Source code: Jnn label

23
The following list shows the instructions that are typically used after a compare operation,
which compares operand1 to operand2: The instructions using the signed and unsigned data
are listed separately

The instructions using unsigned data:

Source code Flags Checked Jump Condition after comparison


JE/JZ ZF=1 equal/zero
JNE/JNZ ZF=0 not equal/not zero
JA/JNBE CF=0, ZF=0 above/not below or equal
JB/JNAE CF=1 below/not above or equal
JAE/JNB CF=0 above or equal/not below
JBE/JNA CF=1 or ZF=1 below or equal/not above

The instructions using signed data:

Source code Flags Checked Jump Condition after comparison


JE/JZ ZF=1 equal/zero
JNE/JNZ ZF=0 not equal/not zero
JG/JNLE ZF=0, SF=OF greater/not less or equal
JL/JNGE SF not= 0F less/not greater or equal
JGE/JNL SF=OF greater or equal/not less
JLE/JNG ZF=1 or SF not= OF less or equal/not greater

The following list shows the instructions that are typically used after an arithmetic/logic or
other instructions.

Source code Flags Checked Jump on testing


JZ ZF=1 zero
JNZ ZF=0 not zero
JS SF=1 sign
JNS SF=0 not sign
JC CF=1 carry
JNC CF=0 not carry
JO OF=1 overflow
JNO OF=0 not overflow
JP/JPE PF=1 parity: even number of bits set in low-
order 8-bit
JNP/JPO PF=0 not parity: odd number of bits set in
low-order 8-bit

JCXZ: Jump if CX Is Zero


The instruction causes a jump to a specified address if CX contains zero. This operation could be
useful at the start of a loop.
Flags: Affects none.
Source code: JCXZ label

INTO: Interrupt on Overflow


Causes an interrupt (usually harmless) if an overflow has occurred (the OF is set to 1) and
performs an INT 04H. The interrupt address is at location 10H of the Interrupt Vector Table.
(See also INT.)
Flags: Affects IF and TF.
Source code: INTO (no operand)

24
STACK OPERATIONS

PUSH: Push onto Stack


The instruction pushes a word onto the stack for later use. SP points to the current word at the
top of the stack. PUSH decrements SP by 2 and transfers a word from the specified operand to
the new top of the stack. The source may be a general register, segment register, or memory.
(See also POP and PUSHF)
Flags: Affects none.
Source code: PUSH register/memory

POP: Pop Word off Stack


Pops a word previously pushed on the stack to a specified destination—a memory location,
general register, or segment register. SP points to the current word at the top of the stack;
POP transfers it to the specified destination and increments SP by 2.
Flags: Affects none.
Source code: POP register/memory

PUSHF: Push Flags onto Stack


The instruction pushes the contents of the Flags register onto the stack for later use. PUSHF
decrements SP by 2. (See also POPF and PUSH.)
Flags: Affects none.
Source code: PUSHF (no operand)

POPF: Pop Flags off Stack


POPF pops the top word from the stack to the 16-bit Flags register and increments SP by 2.
Normally PUSHF has pushed the flags.
Flags: Affects all.
Source code: POPF/POPFD (no operand)

STRING OPERATIONS (Not so important)

MOVS/MOVSB/MOVSW: Move String


These instructions copy data between memory locations. MOVS copies one byte or word
from one location in memory to another. The byte or word copy is done as according to the
operand of the MOVS instruction. The MOVS instruction doesnot load SI and DI.
MOVSB/MOVSW are Normally used with the REP prefix and a length in CX, MOVSB
moves bytes and MOVSW moves words. Operand1 is addressed by ES:DI and operand2 by
DS:SI. If the Direction Flag is 0, the operation moves data from left to right into the operand1
destination and increments DI and SI by 1 or 2. If the DF is 1, the operation moves data from
right to left and decrements DI and SI. REP decrements CX by 1 for each repetition. The
operation ends when CX is decremented to 0; DI and SI are advanced past the last byte
moved.
Flags: Affects none.
Source code: MOVS DST,SRC
[REP] MOVSB/MOVSW (no operand)

LODS/LODSB/LODSW: Load Byte or Word String


The instruction loads the accumulator register with a value from memory. Although LODS is

25
a string operation, it does not require a REP prefix. DS:SI address a byte (if LODSB) or word
(if LODSW) and load it from memory into AL or AX, respectively. If the Direction Flag is 0,
the operation adds 1 (if byte) or 2 (if word) to the SI; otherwise it subtracts 1 or 2.
Flags: Affects none.
Source code: LODS mem or LODS segreg:mem
LODSB/LODSW (no operand)

STOS/STOSB/STOSW: Store String


These instructions store the contents of the accumulator in memory. When used with a REP
prefix along with a count in CX, the operation duplicates a string value a specified number of
times; this is suitable for such actions as clearing an area of memory. For STOSB load the
value in AL and for STOSW load the value in AX. ES:DI reference a location in memory
where the value is to be stored. If the Direction Flag is 0, the operation stores in memory from
left to right and increments DI. If the DF is 1, the operation stores from right to left and
decrements DI. REP decrements CX for each repetition and ends when it becomes 0.
Flags: Affects none.
Source code: [REP] STOSB/STOSW/STOSD (no operand)

CMPS/CMPSB/CMPSW: Compare String


These instructions compare strings of any length in memory. A REPn prefix normally
precedes these instructions, along with a maximum value in CX. CMPSB compares bytes,
and CMPSW compares words. DS:SI address operand1 and ES:DI address operand2. If the
Direction Flag is 0, the operation compares from left to right and increments SI and DI by 1
for byte, 2 for word; if the DF is 1, it compares from right to left and decrements SI and DI.
REPn decrements CX by 1 for each repetition. REPNE ends when the first match is found,
REPE ends when the first nonmatch is found, or both end when CX is decremented to 0; DI
and SI are advanced past the byte that caused termination. The last compare sets/clears the
flags.
Flags: Affects AF, CF, OF, PF, SF, and ZF.
Source code: [REPnn] CMPSB/CMPSW/CMPSD (no operand)

SCAS/SCASB/SCASW: Scan String


These instructions scan a string in memory for a specified value. For SCASB load the value
in AL and for SCASW load it in AX. The ES:DI pair references the string in memory that is
to be scanned. The operations are normally used with a REPE/REPNE prefix, along with a
count in CX: use REPE to find the first nonmatch and REPNE to find the first match. If the
Direction Flag is 0, the operation scans memory from left to right and increments the DI. If
the DF is 1, the operation scans memory from right to left and decrements the DI. REPn
decrements CX for each repetition. The operation ends on an equal (REPNE) or an unequal
(REPE) condition or when CX is decremented to 0. The last compare clears/sets the flags. If
the specified condition is not found, REP has decremented CX to 0; otherwise, DI and SI
contain the address of the following item.
Flags: Affects AF, CF, OF, PF, SF, and ZF.
Source code: [REPnn] SCASB/SCASW/SCASD (no operand)

REP: Repeat String


It repeats a string operation a specified number of times. REP is an optional repeat prefix
coded before the string instructions MOVS, STOS, INS, and OUTS. Load CX with a count

26
prior to execution. For each execution of the string instruction, REP decrements CX by 1 and
repeats the operation until CX is 0, at which point processing continues with the next
instruction. (See also REPE/REPZ/REPNE/REPNZ.)
Flags: See the associated string instructions.
Source code: REP string-instruction

REPE/REPZ/REPNE/REPNZ: Repeat String Conditionally


Repeats a string operation a specified number of times or until a condition is met. REPE,
REPZ, REPNE, and REPNZ are optional repeat prefixes coded before the string instructions
SCAS and CMPS, which change the Zero Flag. Load CX with a count prior to execution. For
REPE/REPZ (repeat while equal/zero), the operation repeats while the ZF is 1 (equal/zero
condition) and CX is not zero. For REPNE/REPNZ (repeat while not equal/zero), the
operation repeats while the ZF is 0 (unequal/nonzero condition) and CX is not zero. While
the conditions are true, the operation decrements CX by 1 and executes the string instruction.
Flags: See the associated string instruction.
Source code: REPE/REPZ/REPNE/REPNZ string-instruction

TYPE CONVERSION

CBW: Convert Byte to Word


It extends a 1-byte signed value to a signed word by duplicating the sign (bit 7) of AL through
the bits in AH.
Flags: Affects none.
Source code: CBW (no operand)

CWD: Convert Word to Doubleword


Extends a one-word signed value to a signed doubleword in DX:AX by duplicating the sign
(bit 15) of AX through DX, typically to generate a 32-bit dividend.
Flags: Affects none.
Source code: CWD (no operand)

MACHINE CONTROL

HLT: Enter Halt State


It causes the processor to enter a halt state while waiting for a hardware interrupt. When an
interrupt occurs, the processor pushes CS and IP onto the stack and executes the interrupt
routine. On return, an IRET instruction pops the stack, and processing resumes following the
original HLT. (An STI operation must first set the IF to enable a hardware interrupt.)
Flags: Affects none.
Source code: HLT (no operand)

LOCK: Lock Bus


It prevents a numeric coprocessor from changing a data item at the same time as the proces-
sor. LOCK is a 1-byte prefix that you may code immediately before any instruction. The
operation sends a signal to the coprocessor to prevent it from using the data until the next
instruction is completed.
Flags: Affects none.
Source code: LOCK instruction

27
WAIT: Put Processor in Wait State
It allows the processor to remain in a wait state until an external interrupt occurs, in order to
synchronize it with a coprocessor. The processor waits until the coprocessor finishes exe-
cuting and resumes processing on receiving a signal in the TEST pin.
Flags: Affects none.
Source code: WAIT (no operand)

NOP: No Operation
Used to delete or insert machine code or to delay execution for purposes of timing. NOP
simply performs a null operation by executing XCHG AX,AX.
Flags: Affects none.
Source code: NOP (no operand)

28

You might also like