awesome-cpus/386Intel/386INTEL.PT2
2016-06-12 22:59:37 -04:00

9919 lines
351 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

PART III COMPATIBILITY
Chapter 13 Executing 80286 Protected-Mode Code
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
13.1 80286 Code Executes as a Subset of the 80386
In general, programs designed for execution in protected mode on an 80286
execute without modification on the 80386, because the features of the 80286
are a subset of those of the 80386.
All the descriptors used by the 80286 are supported by the 80386 as long as
the Intel-reserved word (last word) of the 80286 descriptor is zero.
The descriptors for data segments, executable segments, local descriptor
tables, and task gates are common to both the 80286 and the 80386. Other
80286 descriptorsÄÄTSS segment, call gate, interrupt gate, and trap
gateÄÄare supported by the 80386. The 80386 also has new versions of
descriptors for TSS segment, call gate, interrupt gate, and trap gate that
support the 32-bit nature of the 80386. Both sets of descriptors can be
used simultaneously in the same system.
For those descriptors that are common to both the 80286 and the 80386, the
presence of zeros in the final word causes the 80386 to interpret these
descriptors exactly as 80286 does; for example:
Base Address The high-order eight bits of the 32-bit base address are
zero, limiting base addresses to 24 bits.
Limit The high-order four bits of the limit field are zero,
restricting the value of the limit field to 64K.
Granularity bit The granularity bit is zero, which implies that the value
of the 16-bit limit is interpreted in units of one byte.
B-bit In a data-segment descriptor, the B-bit is zero, implying
that the segment is no larger than 64 Kbytes.
D-bit In an executable-segment descriptor, the D-bit is zero,
implying that 16-bit addressing and operands are the
default.
For formats of these descriptors and documentation of their use refer to
the iAPX 286 Programmer's Reference Manual.
13.2 Two ways to Execute 80286 Tasks
When porting 80286 programs to the 80386, there are two cases to consider:
1. Porting an entire 80286 system to the 80386, complete with 80286
operating system, loader, and system builder.
In this case, all tasks will have 80286 TSSs. The 80386 is being used
as a faster 286.
2. Porting selected 80286 applications to run in an 80386 environment
with an 80386 operating system, loader, and system builder.
In this case, the TSSs used to represent 80286 tasks should be
changed to 80386 TSSs. It is theoretically possible to mix 80286 and
80386 TSSs, but the benefits are slight and the problems are great. It
is recommended that all tasks in a 80386 software system have 80386
TSSs. It is not necessary to change the 80286 object modules
themselves; TSSs are usually constructed by the operating system, by
the loader, or by the system builder. Refer to Chapter 16 for further
discussion of the interface between 16-bit and 32-bit code.
13.3 Differences From 80286
The few differences that do exist primarily affect operating system code.
13.3.1 Wraparound of 80286 24-Bit Physical Address Space
With the 80286, any base and offset combination that addresses beyond 16M
bytes wraps around to the first megabyte of the 80286 address space. With
the 80386, since it has a greater physical address space, any such address
falls into the 17th megabyte. In the unlikely event that any software
depends on this anomaly, the same effect can be simulated on the 80386 by
using paging to map the first 64K bytes of the 17th megabyte of logical
addresses to physical addresses in the first megabyte.
13.3.2 Reserved Word of Descriptor
Because the 80386 uses the contents of the reserved word (last word) of
every descriptor, 80286 programs that place values in this word may not
execute correctly on the 80386.
13.3.3 New Descriptor Type Codes
Operating-system code that manages space in descriptor tables often uses an
invalid value in the access-rights field of descriptor-table entries to
identify unused entries. Access rights values of 80H and 00H remain invalid
for both the 80286 and 80386. Other values that were invalid on for the
80286 may be valid for the 80386 because of the additional descriptor types
defined by the 80386.
13.3.4 Restricted Semantics of LOCK
The 80286 processor implements the bus lock function differently than the
80386. Programs that use forms of memory locking specific to the 80286 may
not execute properly when transported to a specific application of the
80386.
The LOCK prefix and its corresponding output signal should only be used to
prevent other bus masters from interrupting a data movement operation. LOCK
may only be used with the following 80386 instructions when they modify
memory. An undefined-opcode exception results from using LOCK before any
other instruction.
þ Bit test and change: BTS, BTR, BTC.
þ Exchange: XCHG.
þ One-operand arithmetic and logical: INC, DEC, NOT, and NEG.
þ Two-operand arithmetic and logical: ADD, ADC, SUB, SBB, AND, OR, XOR.
A locked instruction is guaranteed to lock only the area of memory defined
by the destination operand, but may lock a larger memory area. For example,
typical 8086 and 80286 configurations lock the entire physical memory space.
With the 80386, the defined area of memory is guaranteed to be locked
against access by a processor executing a locked instruction on exactly the
same memory area, i.e., an operand with identical starting address and
identical length.
13.3.5 Additional Exceptions
The 80386 defines new exceptions that can occur even in systems designed
for the 80286.
þ Exception #6 ÄÄ invalid opcode
This exception can result from improper use of the LOCK instruction.
þ Exception #14 ÄÄ page fault
This exception may occur in an 80286 program if the operating system
enables paging. Paging can be used in a system with 80286 tasks as long
as all tasks use the same page directory. Because there is no place in
an 80286 TSS to store the PDBR, switching to an 80286 task does not
change the value of PDBR. Tasks ported from the 80286 should be given
80386 TSSs so they can take full advantage of paging.
Chapter 14 80386 Real-Address Mode
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
The real-address mode of the 80386 executes object code designed for
execution on 8086, 8088, 80186, or 80188 processors, or for execution in the
real-address mode of an 80286:
In effect, the architecture of the 80386 in this mode is almost identical
to that of the 8086, 8088, 80186, and 80188. To a programmer, an 80386 in
real-address mode appears as a high-speed 8086 with extensions to the
instruction set and registers. The principal features of this architecture
are defined in Chapters 2 and 3.
This chapter discusses certain additional topics that complete the system
programmer's view of the 80386 in real-address mode:
þ Address formation.
þ Extensions to registers and instructions.
þ Interrupt and exception handling.
þ Entering and leaving real-address mode.
þ Real-address-mode exceptions.
þ Differences from 8086.
þ Differences from 80286 real-address mode.
14.1 Physical Address Formation
The 80386 provides a one Mbyte + 64 Kbyte memory space for an 8086 program.
Segment relocation is performed as in the 8086: the 16-bit value in a
segment selector is shifted left by four bits to form the base address of a
segment. The effective address is extended with four high order zeros and
added to the base to form a linear address as Figure 14-1 illustrates. (The
linear address is equivalent to the physical address, because paging is not
used in real-address mode.) Unlike the 8086, the resulting linear address
may have up to 21 significant bits. There is a possibility of a carry when
the base address is added to the effective address. On the 8086, the carried
bit is truncated, whereas on the 80386 the carried bit is stored in bit
position 20 of the linear address.
Unlike the 8086 and 80286, 32-bit effective addresses can be generated (via
the address-size prefix); however, the value of a 32-bit address may not
exceed 65535 without causing an exception. For full compatibility with 80286
real-address mode, pseudo-protection faults (interrupt 12 or 13 with no
error code) occur if an effective address is generated outside the range 0
through 65535.
Figure 14-1. Real-Address Mode Address Formation
19 3 0
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍ»
BASE º 16-BIT SEGMENT SELECTOR ³ 0 0 0 0 º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍͼ
+
19 15 0
ÉÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
OFFSET º 0 0 0 0 ³ 16-BIT EFFECTIVE ADDRESS º
ÈÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
=
20 0
LINEAR ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ADDRESS º X X X X X X X X X X X X X X X X X X X X X X º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
14.2 Registers and Instructions
The register set available in real-address mode includes all the registers
defined for the 8086 plus the new registers introduced by the 80386: FS, GS,
debug registers, control registers, and test registers. New instructions
that explicitly operate on the segment registers FS and GS are available,
and the new segment-override prefixes can be used to cause instructions to
utilize FS and GS for address calculations. Instructions can utilize 32-bit
operands through the use of the operand size prefix.
The instruction codes that cause undefined opcode traps (interrupt 6)
include instructions of the protected mode that manipulate or interrogate
80386 selectors and descriptors; namely, VERR, VERW, LAR, LSL, LTR, STR,
LLDT, and SLDT. Programs executing in real-address mode are able to take
advantage of the new applications-oriented instructions added to the
architecture by the introduction of the 80186/80188, 80286 and 80386:
þ New instructions introduced by 80186/80188 and 80286.
ÄÄ PUSH immediate data
ÄÄ Push all and pop all (PUSHA and POPA)
ÄÄ Multiply immediate data
ÄÄ Shift and rotate by immediate count
ÄÄ String I/O
ÄÄ ENTER and LEAVE
ÄÄ BOUND
þ New instructions introduced by 80386.
ÄÄ LSS, LFS, LGS instructions
ÄÄ Long-displacement conditional jumps
ÄÄ Single-bit instructions
ÄÄ Bit scan
ÄÄ Double-shift instructions
ÄÄ Byte set on condition
ÄÄ Move with sign/zero extension
ÄÄ Generalized multiply
ÄÄ MOV to and from control registers
ÄÄ MOV to and from test registers
ÄÄ MOV to and from debug registers
14.3 Interrupt and Exception Handling
Interrupts and exceptions in 80386 real-address mode work as much as they
do on an 8086. Interrupts and exceptions vector to interrupt procedures via
an interrupt table. The processor multiplies the interrupt or exception
identifier by four to obtain an index into the interrupt table. The entries
of the interrupt table are far pointers to the entry points of interrupt or
exception handler procedures. When an interrupt occurs, the processor
pushes the current values of CS:IP onto the stack, disables interrupts,
clears TF (the single-step flag), then transfers control to the location
specified in the interrupt table. An IRET instruction at the end of the
handler procedure reverses these steps before returning control to the
interrupted procedure.
The primary difference in the interrupt handling of the 80386 compared to
the 8086 is that the location and size of the interrupt table depend on the
contents of the IDTR (IDT register). Ordinarily, this fact is not apparent
to programmers, because, after RESET, the IDTR contains a base address of 0
and a limit of 3FFH, which is compatible with the 8086. However, the LIDT
instruction can be used in real-address mode to change the base and limit
values in the IDTR. Refer to Chapter 9 for details on the IDTR, and the
LIDT and SIDT instructions. If an interrupt occurs and the corresponding
entry of the interrupt table is beyond the limit stored in the IDTR, the
processor raises exception 8.
14.4 Entering and Leaving Real-Address Mode
Real-address mode is in effect after a signal on the RESET pin. Even if the
system is going to be used in protected mode, the start-up program will
execute in real-address mode temporarily while initializing for protected
mode.
14.4.1 Switching to Protected Mode
The only way to leave real-address mode is to switch to protected mode. The
processor enters protected mode when a MOV to CR0 instruction sets the PE
(protection enable) bit in CR0. (For compatibility with the 80286, the LMSW
instruction may also be used to set the PE bit.)
Refer to Chapter 10 "Initialization" for other aspects of switching to
protected mode.
14.5 Switching Back to Real-Address Mode
The processor reenters real-address mode if software clears the PE bit in
CR0 with a MOV to CR0 instruction. A procedure that attempts to do this,
however, should proceed as follows:
1. If paging is enabled, perform the following sequence:
þ Transfer control to linear addresses that have an identity mapping;
i.e., linear addresses equal physical addresses.
þ Clear the PG bit in CR0.
þ Move zeros to CR3 to clear out the paging cache.
2. Transfer control to a segment that has a limit of 64K (FFFFH). This
loads the CS register with the limit it needs to have in real mode.
3. Load segment registers SS, DS, ES, FS, and GS with a selector that
points to a descriptor containing the following values, which are
appropriate to real mode:
þ Limit = 64K (FFFFH)
þ Byte granular (G = 0)
þ Expand up (E = 0)
þ Writable (W = 1)
þ Present (P = 1)
þ Base = any value
4. Disable interrupts. A CLI instruction disables INTR interrupts. NMIs
can be disabled with external circuitry.
5. Clear the PE bit.
6. Jump to the real mode code to be executed using a far JMP. This
action flushes the instruction queue and puts appropriate values in
the access rights of the CS register.
7. Use the LIDT instruction to load the base and limit of the real-mode
interrupt vector table.
8. Enable interrupts.
9. Load the segment registers as needed by the real-mode code.
14.6 Real-Address Mode Exceptions
The 80386 reports some exceptions differently when executing in
real-address mode than when executing in protected mode. Table 14-1 details
the real-address-mode exceptions.
14.7 Differences From 8086
In general, the 80386 in real-address mode will correctly execute ROM-based
software designed for the 8086, 8088, 80186, and 80188. Following is a list
of the minor differences between 8086 execution on the 80386 and on an 8086.
1. Instruction clock counts.
The 80386 takes fewer clocks for most instructions than the 8086/8088.
The areas most likely to be affected are:
þ Delays required by I/O devices between I/O operations.
þ Assumed delays with 8086/8088 operating in parallel with an 8087.
2. Divide Exceptions Point to the DIV instruction.
Divide exceptions on the 80386 always leave the saved CS:IP value
pointing to the instruction that failed. On the 8086/8088, the CS:IP
value points to the next instruction.
3. Undefined 8086/8088 opcodes.
Opcodes that were not defined for the 8086/8088 will cause exception
6 or will execute one of the new instructions defined for the 80386.
4. Value written by PUSH SP.
The 80386 pushes a different value on the stack for PUSH SP than the
8086/8088. The 80386 pushes the value of SP before SP is incremented
as part of the push operation; the 8086/8088 pushes the value of SP
after it is incremented. If the value pushed is important, replace
PUSH SP instructions with the following three instructions:
PUSH BP
MOV BP, SP
XCHG BP, [BP]
This code functions as the 8086/8088 PUSH SP instruction on the 80386.
5. Shift or rotate by more than 31 bits.
The 80386 masks all shift and rotate counts to the low-order five
bits. This MOD 32 operation limits the count to a maximum of 31 bits,
thereby limiting the time that interrupt response is delayed while
the instruction is executing.
6. Redundant prefixes.
The 80386 sets a limit of 15 bytes on instruction length. The only
way to violate this limit is by putting redundant prefixes before an
instruction. Exception 13 occurs if the limit on instruction length
is violated. The 8086/8088 has no instruction length limit.
7. Operand crossing offset 0 or 65,535.
On the 8086, an attempt to access a memory operand that crosses
offset 65,535 (e.g., MOV a word to offset 65,535) or offset 0 (e.g.,
PUSH a word when SP = 1) causes the offset to wrap around modulo
65,536. The 80386 raises an exception in these casesÄÄexception 13 if
the segment is a data segment (i.e., if CS, DS, ES, FS, or GS is being
used to address the segment), exception 12 if the segment is a stack
segment (i.e., if SS is being used).
8. Sequential execution across offset 65,535.
On the 8086, if sequential execution of instructions proceeds past
offset 65,535, the processor fetches the next instruction byte from
offset 0 of the same segment. On the 80386, the processor raises
exception 13 in such a case.
9. LOCK is restricted to certain instructions.
The LOCK prefix and its corresponding output signal should only be
used to prevent other bus masters from interrupting a data movement
operation. The 80386 always asserts the LOCK signal during an XCHG
instruction with memory (even if the LOCK prefix is not used). LOCK
may only be used with the following 80386 instructions when they
update memory: BTS, BTR, BTC, XCHG, ADD, ADC, SUB, SBB, INC, DEC,
AND, OR, XOR, NOT, and NEG. An undefined-opcode exception
(interrupt 6) results from using LOCK before any other instruction.
10. Single-stepping external interrupt handlers.
The priority of the 80386 single-step exception is different from that
of the 8086/8088. The change prevents an external interrupt handler
from being single-stepped if the interrupt occurs while a program is
being single-stepped. The 80386 single-step exception has higher
priority that any external interrupt. The 80386 will still single-step
through an interrupt handler invoked by the INT instructions or by an
exception.
11. IDIV exceptions for quotients of 80H or 8000H.
The 80386 can generate the largest negative number as a quotient for
the IDIV instruction. The 8086/8088 causes exception zero instead.
12. Flags in stack.
The setting of the flags stored by PUSHF, by interrupts, and by
exceptions is different from that stored by the 8086 in bit positions
12 through 15. On the 8086 these bits are stored as ones, but in
80386 real-address mode bit 15 is always zero, and bits 14 through 12
reflect the last value loaded into them.
13. NMI interrupting NMI handlers.
After an NMI is recognized on the 80386, the NMI interrupt is masked
until an IRET instruction is executed.
14. Coprocessor errors vector to interrupt 16.
Any 80386 system with a coprocessor must use interrupt vector 16 for
the coprocessor error exception. If an 8086/8088 system uses another
vector for the 8087 interrupt, both vectors should point to the
coprocessor-error exception handler.
15. Numeric exception handlers should allow prefixes.
On the 80386, the value of CS:IP saved for coprocessor exceptions
points at any prefixes before an ESC instruction. On 8086/8088
systems, the saved CS:IP points to the ESC instruction.
16. Coprocessor does not use interrupt controller.
The coprocessor error signal to the 80386 does not pass through an
interrupt controller (an 8087 INT signal does). Some instructions in
a coprocessor error handler may need to be deleted if they deal with
the interrupt controller.
17. Six new interrupt vectors.
The 80386 adds six exceptions that arise only if the 8086 program has
a hidden bug. It is recommended that exception handlers be added that
treat these exceptions as invalid operations. This additional
software does not significantly affect the existing 8086 software
because the interrupts do not normally occur. These interrupt
identifiers should not already have been used by the 8086 software,
because they are in the range reserved by Intel. Table 14-2 describes
the new 80386 exceptions.
18. One megabyte wraparound.
The 80386 does not wrap addresses at 1 megabyte in real-address mode.
On members of the 8086 family, it possible to specify addresses
greater than one megabyte. For example, with a selector value 0FFFFH
and an offset of 0FFFFH, the effective address would be 10FFEFH (1
Mbyte + 65519). The 8086, which can form adresses only up to 20 bits
long, truncates the high-order bit, thereby "wrapping" this address
to 0FFEFH. However, the 80386, which can form addresses up to 32
bits long does not truncate such an address.
Table 14-1. 80386 Real-Address Mode Exceptions
Description Interrupt Function that Can
Return Address
Number Generate the Exception
Points to Faulting
Instruction
Divide error 0 DIV, IDIV
YES
Debug exceptions 1 All
Some debug exceptions point to the faulting instruction, others to the
next instruction. The exception handler can determine which has occurred by
examining DR6.
Breakpoint 3 INT
NO
Overflow 4 INTO
NO
Bounds check 5 BOUND
YES
Invalid opcode 6 Any undefined opcode or LOCK
YES
used with wrong instruction
Coprocessor not available 7 ESC or WAIT
YES
Interrupt table limit too small 8 INT vector is not within IDTR
YES
limit
Reserved 9-12
Stack fault 12 Memory operand crosses offset
YES
0 or 0FFFFH
Pseudo-protection exception 13 Memory operand crosses offset
YES
0FFFFH or attempt to execute
past offset 0FFFFH or
instruction longer than 15
bytes
Reserved 14,15
Coprocessor error 16 ESC or WAIT
YES
Coprocessor errors are reported on the first ESC or WAIT instruction
after the ESC instruction that caused the error.
Two-byte SW interrupt 0-255 INT n
NO
Table 14-2. New 80386 Exceptions
Interrupt Function
Identifier
5 A BOUND instruction was executed with a register value outside
the limit values.
6 An undefined opcode was encountered or LOCK was used improperly
before an instruction to which it does not apply.
7 The EM bit in the MSW is set when an ESC instruction was
encountered. This exception also occurs on a WAIT instruction
if TS is set.
8 An exception or interrupt has vectored to an interrupt table
entry beyond the interrupt table limit in IDTR. This can occur
only if the LIDT instruction has changed the limit from the
default value of 3FFH, which is enough for all 256 interrupt
IDs.
12 Operand crosses extremes of stack segment, e.g., MOV operation
at offset 0FFFFH or push with SP=1 during PUSH, CALL, or INT.
13 Operand crosses extremes of a segment other than a stack
segment; or sequential instruction execution attempts to
proceed beyond offset 0FFFFH; or an instruction is longer than
15 bytes (including prefixes).
14.8 Differences From 80286 Real-Address Mode
The few differences that exist between 80386 real-address mode and 80286
real-address mode are not likely to affect any existing 80286 programs
except possibly the system initialization procedures.
14.8.1 Bus Lock
The 80286 processor implements the bus lock function differently than the
80386. Programs that use forms of memory locking specific to the 80286 may
not execute properly if transported to a specific application of the 80386.
The LOCK prefix and its corresponding output signal should only be used to
prevent other bus masters from interrupting a data movement operation. LOCK
may only be used with the following 80386 instructions when they modify
memory. An undefined-opcode exception results from using LOCK before any
other instruction.
þ Bit test and change: BTS, BTR, BTC.
þ Exchange: XCHG.
þ One-operand arithmetic and logical: INC, DEC, NOT, and NEG.
þ Two-operand arithmetic and logical: ADD, ADC, SUB, SBB, AND, OR, XOR.
A locked instruction is guaranteed to lock only the area of memory defined
by the destination operand, but may lock a larger memory area. For example,
typical 8086 and 80286 configurations lock the entire physical memory space.
With the 80386, the defined area of memory is guranteed to be locked against
access by a processor executing a locked instruction on exactly the same
memory area, i.e., an operand with identical starting address and identical
length.
14.8.2 Location of First Instruction
The starting location is 0FFFFFFF0H (sixteen bytes from end of 32-bit
address space) on the 80386 rather than 0FFFFF0H (sixteen bytes from end of
24-bit address space) as on the 80286. Many 80286 ROM initialization
programs will work correctly in this new environment. Others can be made to
work correctly with external hardware that redefines the signals on
A{31-20}.
14.8.3 Initial Values of General Registers
On the 80386, certain general registers may contain different values after
RESET than on the 80286. This should not cause compatibility problems,
because the content of 8086 registers after RESET is undefined. If
self-test is requested during the reset sequence and errors are detected in
the 80386 unit, EAX will contain a nonzero value. EDX contains the component
and revision identifier. Refer to Chapter 10 for more information.
14.8.4 MSW Initialization
The 80286 initializes the MSW register to FFF0H, but the 80386 initializes
this register to 0000H. This difference should have no effect, because the
bits that are different are undefined on the 80286. Programs that read the
value of the MSW will behave differently on the 80386 only if they depend on
the setting of the undefined, high-order bits.
Chapter 15 Virtual 8086 Mode
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
The 80386 supports execution of one or more 8086, 8088, 80186, or 80188
programs in an 80386 protected-mode environment. An 8086 program runs in
this environment as part of a V86 (virtual 8086) task. V86 tasks take
advantage of the hardware support of multitasking offered by the protected
mode. Not only can there be multiple V86 tasks, each one executing an 8086
program, but V86 tasks can be multiprogrammed with other 80386 tasks.
The purpose of a V86 task is to form a "virtual machine" with which to
execute an 8086 program. A complete virtual machine consists not only of
80386 hardware but also of systems software. Thus, the emulation of an 8086
is the result of cooperation between hardware and software:
þ The hardware provides a virtual set of registers (via the TSS), a
virtual memory space (the first megabyte of the linear address space of
the task), and directly executes all instructions that deal with these
registers and with this address space.
þ The software controls the external interfaces of the virtual machine
(I/O, interrupts, and exceptions) in a manner consistent with the
larger environment in which it executes. In the case of I/O, software
can choose either to emulate I/O instructions or to let the hardware
execute them directly without software intervention.
Software that helps implement virtual 8086 machines is called a V86
monitor.
15.1 Executing 8086 Code
The processor executes in V86 mode when the VM (virtual machine) bit in the
EFLAGS register is set. The processor tests this flag under two general
conditions:
1. When loading segment registers to know whether to use 8086-style
address formation.
2. When decoding instructions to determine which instructions are
sensitive to IOPL.
Except for these two modifications to its normal operations, the 80386 in
V86 mode operated much as in protected mode.
15.1.1 Registers and Instructions
The register set available in V86 mode includes all the registers defined
for the 8086 plus the new registers introduced by the 80386: FS, GS, debug
registers, control registers, and test registers. New instructions that
explicitly operate on the segment registers FS and GS are available, and the
new segment-override prefixes can be used to cause instructions to utilize
FS and GS for address calculations. Instructions can utilize 32-bit
operands through the use of the operand size prefix.
8086 programs running as V86 tasks are able to take advantage of the new
applications-oriented instructions added to the architecture by the
introduction of the 80186/80188, 80286 and 80386:
þ New instructions introduced by 80186/80188 and 80286.
ÄÄ PUSH immediate data
ÄÄ Push all and pop all (PUSHA and POPA)
ÄÄ Multiply immediate data
ÄÄ Shift and rotate by immediate count
ÄÄ String I/O
ÄÄ ENTER and LEAVE
ÄÄ BOUND
þ New instructions introduced by 80386.
ÄÄ LSS, LFS, LGS instructions
ÄÄ Long-displacement conditional jumps
ÄÄ Single-bit instructions
ÄÄ Bit scan
ÄÄ Double-shift instructions
ÄÄ Byte set on condition
ÄÄ Move with sign/zero extension
ÄÄ Generalized multiply
15.1.2 Linear Address Formation
In V86 mode, the 80386 processor does not interpret 8086 selectors by
referring to descriptors; instead, it forms linear addresses as an 8086
would. It shifts the selector left by four bits to form a 20-bit base
address. The effective address is extended with four high-order zeros and
added to the base address to create a linear address as Figure 15-1
illustrates.
Because of the possibility of a carry, the resulting linear address may
contain up to 21 significant bits. An 8086 program may generate linear
addresses anywhere in the range 0 to 10FFEFH (one megabyte plus
approximately 64 Kbytes) of the task's linear address space.
V86 tasks generate 32-bit linear addresses. While an 8086 program can only
utilize the low-order 21 bits of a linear address, the linear address can be
mapped via page tables to any 32-bit physical address.
Unlike the 8086 and 80286, 32-bit effective addresses can be generated (via
the address-size prefix); however, the value of a 32-bit address may not
exceed 65,535 without causing an exception. For full compatibility with
80286 real-address mode, pseudo-protection faults (interrupt 12 or 13 with
no error code) occur if an address is generated outside the range 0 through
65,535.
Figure 15-1. V86 Mode Address Formation
19 3 0
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍ»
BASE º 16-BIT SEGMENT SELECTOR ³ 0 0 0 0 º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍͼ
+
19 15 0
ÉÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
OFFSET º 0 0 0 0 ³ 16-BIT EFFECTIVE ADDRESS º
ÈÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
=
20 0
LINEAR ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ADDRESS º X X X X X X X X X X X X X X X X X X X X X X º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
15.2 Structure of a V86 Task
A V86 task consists partly of the 8086 program to be executed and partly of
80386 "native mode" code that serves as the virtual-machine monitor. The
task must be represented by an 80386 TSS (not an 80286 TSS). The processor
enters V86 mode to execute the 8086 program and returns to protected mode to
execute the monitor or other 80386 tasks.
To run successfully in V86 mode, an existing 8086 program needs the
following:
þ A V86 monitor.
þ Operating-system services.
The V86 monitor is 80386 protected-mode code that executes at
privilege-level zero. The monitor consists primarily of initialization and
exception-handling procedures. As for any other 80386 program,
executable-segment descriptors for the monitor must exist in the GDT or in
the task's LDT. The linear addresses above 10FFEFH are available for the
V86 monitor, the operating system, and other systems software. The monitor
may also need data-segment descriptors so that it can examine the interrupt
vector table or other parts of the 8086 program in the first megabyte of the
address space.
In general, there are two options for implementing the 8086 operating
system:
1. The 8086 operating system may run as part of the 8086 code. This
approach is desirable for any of the following reasons:
þ The 8086 applications code modifies the operating system.
þ There is not sufficient development time to reimplement the 8086
operating system as 80386 code.
2. The 8086 operating system may be implemented or emulated in the V86
monitor. This approach is desirable for any of the following reasons:
þ Operating system functions can be more easily coordinated among
several V86 tasks.
þ The functions of the 8086 operating system can be easily emulated
by calls to the 80386 operating system.
Note that, regardless of the approach chosen for implementing the 8086
operating system, different V86 tasks may use different 8086 operating
systems.
15.2.1 Using Paging for V86 Tasks
Paging is not necessary for a single V86 task, but paging is useful or
necessary for any of the following reasons:
þ To create multiple V86 tasks. Each task must map the lower megabyte of
linear addresses to different physical locations.
þ To emulate the megabyte wrap. On members of the 8086 family, it is
possible to specify addresses larger than one megabyte. For example,
with a selector value of 0FFFFH and an offset of 0FFFFH, the effective
address would be 10FFEFH (one megabyte + 65519). The 8086, which can
form addresses only up to 20 bits long, truncates the high-order bit,
thereby "wrapping" this address to 0FFEFH. The 80386, however, which
can form addresses up to 32 bits long does not truncate such an
address. If any 8086 programs depend on this addressing anomaly, the
same effect can be achieved in a V86 task by mapping linear addresses
between 100000H and 110000H and linear addresses between 0 and 10000H
to the same physical addresses.
þ To create a virtual address space larger than the physical address
space.
þ To share 8086 OS code or ROM code that is common to several 8086
programs that are executing simultaneously.
þ To redirect or trap references to memory-mapped I/O devices.
15.2.2 Protection within a V86 Task
Because it does not refer to descriptors while executing 8086 programs, the
processor also does not utilize the protection mechanisms offered by
descriptors. To protect the systems software that runs in a V86 task from
the 8086 program, software designers may follow either of these approaches:
þ Reserve the first megabyte (plus 64 kilobytes) of each task's linear
address space for the 8086 program. An 8086 task cannot generate
addresses outside this range.
þ Use the U/S bit of page-table entries to protect the virtual-machine
monitor and other systems software in each virtual 8086 task's space.
When the processor is in V86 mode, CPL is 3. Therefore, an 8086 program
has only user privileges. If the pages of the virtual-machine monitor
have supervisor privilege, they cannot be accessed by the 8086 program.
15.3 Entering and Leaving V86 Mode
Figure 15-2 summarizes the ways that the processor can enter and leave an
8086 program. The processor can enter V86 by either of two means:
1. A task switch to an 80386 task loads the image of EFLAGS from the new
TSS. The TSS of the new task must be an 80386 TSS, not an 80286 TSS,
because the 80286 TSS does not store the high-order word of EFLAGS,
which contains the VM flag. A value of one in the VM bit of the new
EFLAGS indicates that the new task is executing 8086 instructions;
therefore, while loading the segment registers from the TSS, the
processor forms base addresses as the 8086 would.
2. An IRET from a procedure of an 80386 task loads the image of EFLAGS
from the stack. A value of one in VM in this case indicates that the
procedure to which control is being returned is an 8086 procedure. The
CPL at the time the IRET is executed must be zero, else the processor
does not change VM.
The processor leaves V86 mode when an interrupt or exception occurs. There
are two cases:
1. The interrupt or exception causes a task switch. A task switch from a
V86 task to any other task loads EFLAGS from the TSS of the new task.
If the new TSS is an 80386 TSS and the VM bit in the EFLAGS image is
zero or if the new TSS is an 80286 TSS, then the processor clears the
VM bit of EFLAGS, loads the segment registers from the new TSS using
80386-style address formation, and begins executing the instructions
of the new task according to 80386 protected-mode semantics.
2. The interrupt or exception vectors to a privilege-level zero
procedure. The processor stores the current setting of EFLAGS on the
stack, then clears the VM bit. The interrupt or exception handler,
therefore, executes as "native" 80386 protected-mode code. If an
interrupt or exception vectors to a conforming segment or to a
privilege level other than three, the processor causes a
general-protection exception; the error code is the selector of the
executable segment to which transfer was attempted.
Systems software does not manipulate the VM flag directly, but rather
manipulates the image of the EFLAGS register that is stored on the stack or
in the TSS. The V86 monitor sets the VM flag in the EFLAGS image on the
stack or in the TSS when first creating a V86 task. Exception and interrupt
handlers can examine the VM flag on the stack. If the interrupted procedure
was executing in V86 mode, the handler may need to invoke the V86 monitor.
Figure 15-2. Entering and Leaving the 8086 Program
MODE TRANSITION DIAGRAM
ÉÍÍÍÍÍÍÍÍÍÍÍ»
TASK SWITCH º INITIAL º
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ ENTRY º
³ OR IRET ÈÍÍÍÍÍÍÍÍÍÍͼ
³

ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» INTERRUPT, EXCEPTION ÉÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º 8086 PROGRAM ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĺ V86 MONITOR º
º (V86 MODE) ºÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ (PROTECTED º
ÈÍÍÍÍÍÍÍÑÍÍÍÍÍͼ IRET º MODE) º
 ³ ÈÍÍÍÍÍÑÍÍÍÍÍÍͼ
³ ³ ³ 
³ ³ ³ ³
³ ³ ³ ³
³ ³TASK SWITCH ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» TASK SWITCH ³
³ ÀÄÄÄÄÄÄÄÄÄÄĺ OTHER 80386 TASKS ºÄÄÄÄÄÄÄÄÄÙ ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄĶ (PROTECTED MODE) ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
TASK SWITCH ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ TASK SWITCH
15.3.1 Transitions Through Task Switches
A task switch to or from a V86 task may be due to any of three causes:
1. An interrupt that vectors to a task gate.
2. An action of the scheduler of the 80386 operating system.
3. An IRET when the NT flag is set.
In any of these cases, the processor changes the VM bit in EFLAGS according
to the image of EFLAGS in the new TSS. If the new TSS is an 80286 TSS, the
high-order word of EFLAGS is not in the TSS; the processor clears VM in this
case. The processor updates VM prior to loading the segment registers from
the images in the new TSS. The new setting of VM determines whether the
processor interprets the new segment-register images as 8086 selectors or
80386/80286 selectors.
15.3.2 Transitions Through Trap Gates and Interrupt Gates
The processor leaves V86 mode as the result of an exception or interrupt
that vectors via a trap or interrupt gate to a privilege-level zero
procedure. The exception or interrupt handler returns to the 8086 code by
executing an IRET.
Because it was designed for execution by an 8086 processor, an 8086 program
in a V86 task will have an 8086-style interrupt table starting at linear
address zero. However, the 80386 does not use this table directly. For all
exceptions and interrupts that occur in V86 mode, the processor vectors
through the IDT. The IDT entry for an interrupt or exception that occurs in
a V86 task must contain either:
þ A task gate.
þ An 80386 trap gate (type 14) or an 80386 interrupt gate (type 15),
which must point to a nonconforming, privilege-level zero, code
segment.
Interrupts and exceptions that have 80386 trap or interrupt gates in the
IDT vector to the appropriate handler procedure at privilege-level zero. The
contents of all the 8086 segment registers are stored on the PL 0 stack.
Figure 15-3 shows the format of the PL 0 stack after an exception or
interrupt that occurs while a V86 task is executing an 8086 program.
After the processor stores all the 8086 segment registers on the PL 0
stack, it loads all the segment registers with zeros before starting to
execute the handler procedure. This permits the interrupt handler to safely
save and restore the DS, ES, FS, and GS registers as 80386 selectors.
Interrupt handlers that may be invoked in the context of either a regular
task or a V86 task, can use the same prolog and epilog code for register
saving regardless of the kind of task. Restoring zeros to these registers
before execution of the IRET does not cause a trap in the interrupt handler.
Interrupt procedures that expect values in the segment registers or that
return values via segment registers have to use the register images stored
on the PL 0 stack. Interrupt handlers that need to know whether the
interrupt occurred in V86 mode can examine the VM bit in the stored EFLAGS
image.
An interrupt handler passes control to the V86 monitor if the VM bit is set
in the EFLAGS image stored on the stack and the interrupt or exception is
one that the monitor needs to handle. The V86 monitor may either:
þ Handle the interrupt completely within the V86 monitor.
þ Invoke the 8086 program's interrupt handler.
Reflecting an interrupt or exception back to the 8086 code involves the
following steps:
1. Refer to the 8086 interrupt vector to locate the appropriate handler
procedure.
2. Store the state of the 8086 program on the privilege-level three
stack.
3. Change the return link on the privilege-level zero stack to point to
the privilege-level three handler procedure.
4. Execute an IRET so as to pass control to the handler.
5. When the IRET by the privilege-level three handler again traps to the
V86 monitor, restore the return link on the privilege-level zero stack
to point to the originally interrupted, privilege-level three
procedure.
6. Execute an IRET so as to pass control back to the interrupted
procedure.
Figure 15-3. PL 0 Stack after Interrupt in V86 Task
WITHOUT ERROR CODE WITH ERROR CODE
31 0 31 0
ÉÍÍÍÍÍÍËÍÍÍÍÍÍÍ»ÄÄÄÄ¿ ÉÍÍÍÍÍÍËÍÍÍÍÍÍÍ»ÄÄÄÄ¿
º±±±±±±ºOLD GS º ³ º±±±±±±ºOLD GS º ³
ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ SS:ESP ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ SS:ESP
D O º±±±±±±ºOLD FS º FROM TSS º±±±±±±ºOLD FS º FROM TSS
I F ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹
R º±±±±±±ºOLD DS º º±±±±±±ºOLD DS º
E E ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹
C X º±±±±±±ºOLD ES º º±±±±±±ºOLD ES º
T P ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÎÍÍÍÍÍÍ͹
I A º±±±±±±ºOLD SS º º±±±±±±ºOLD SS º
O N ÌÍÍÍÍÍÍÊÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÊÍÍÍÍÍÍ͹
N S º OLD ESP º º OLD ESP º
I ÌÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
³ O º OLD EFLAGS º º OLD EFLAGS º
³ N ÌÍÍÍÍÍÍËÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍËÍÍÍÍÍÍ͹
³ º±±±±±±ºOLD CS º NEW º±±±±±±ºOLD CS º
 ÌÍÍÍÍÍÍÊÍÍÍÍÍÍ͹ SS:EIP ÌÍÍÍÍÍÍÊÍÍÍÍÍÍ͹
º OLD EIP º ³ º OLD EIP º NEW
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ÄÄÄÙ ÌÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ SS:EIP
º º º ERROR CODE º ³
  ÌÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ÄÄÄÙ
  º º
   
15.4 Additional Sensitive Instructions
When the 80386 is executing in V86 mode, the instructions PUSHF, POPF,
INT n, and IRET are sensitive to IOPL. The instructions IN, INS, OUT, and
OUTS, which are ordinarily sensitive in protected mode, are not sensitive
in V86 mode. Following is a complete list of instructions that are sensitive
in V86 mode:
CLI ÄÄ Clear Interrupt-Enable Flag
STI ÄÄ Set Interrupt-Enable Flag
LOCK ÄÄ Assert Bus-Lock Signal
PUSHF ÄÄ Push Flags
POPF ÄÄ Pop Flags
INT n ÄÄ Software Interrupt
RET ÄÄ Interrupt Return
CPL is always three in V86 mode; therefore, if IOPL < 3, these instructions
will trigger a general-protection exceptions. These instructions are made
sensitive so that their functions can be simulated by the V86 monitor.
15.4.1 Emulating 8086 Operating System Calls
INT n is sensitive so that the V86 monitor can intercept calls to the
8086 OS. Many 8086 operating systems are called by pushing parameters onto
the stack, then executing an INT n instruction. If IOPL < 3, INT n
instructions will be intercepted by the V86 monitor. The V86 monitor can
then emulate the function of the 8086 operating system or reflect the
interrupt back to the 8086 operating system in V86 mode.
15.4.2 Virtualizing the Interrupt-Enable Flag
When the processor is executing 8086 code in a V86 task, the instructions
PUSHF, POPF, and IRET are sensitive to IOPL so that the V86 monitor can
control changes to the interrupt-enable flag (IF). Other instructions that
affect IF (STI and CLI) are IOPL sensitive both in 8086 code and in
80386/80386 code.
Many 8086 programs that were designed to execute on single-task systems set
and clear IF to control interrupts. However, when these same programs are
executed in a multitasking environment, such control of IF can be
disruptive. If IOPL is less than three, all instructions that change or
interrogate IF will trap to the V86 monitor. The V86 monitor can then
control IF in a manner that both suits the needs of the larger environment
and is transparent to the 8086 program.
15.5 Virtual I/O
Many 8086 programs that were designed to execute on single-task systems use
I/O devices directly. However, when these same programs are executed in a
multitasking environment, such use of devices can be disruptive. The 80386
provides sufficient flexibility to control I/O in a manner that both suits
the needs of the new environment and is transparent to the 8086 program.
Designers may take any of several possible approaches to controlling I/O:
þ Implement or emulate the 8086 operating system as an 80386 program and
require the 8086 application to do I/O via software interrupts to the
operating system, trapping all attempts to do I/O directly.
þ Let the 8086 program take complete control of all I/O.
þ Selectively trap and emulate references that a task makes to specific
I/O ports.
þ Trap or redirect references to memory-mapped I/O addresses.
The method of controlling I/O depends upon whether I/O ports are I/O mapped
or memory mapped.
15.5.1 I/O-Mapped I/O
I/O-mapped I/O in V86 mode differs from protected mode only in that the
protection mechanism does not consult IOPL when executing the I/O
instructions IN, INS, OUT, OUTS. Only the I/O permission bit map controls
the right for V86 tasks to execute these I/O instructions.
The I/O permission map traps I/O instructions selectively depending on the
I/O addresses to which they refer. The I/O permission bit map of each V86
task determines which I/O addresses are trapped for that task. Because each
task may have a different I/O permission bit map, the addresses trapped for
one task may be different from those trapped for others. Refer to Chapter 8
for more information about the I/O permission map.
15.5.2 Memory-Mapped I/O
In hardware designs that utilize memory-mapped I/O, the paging facilities
of the 80386 can be used to trap or redirect I/O operations. Each task that
executes memory-mapped I/O must have a page (or pages) for the memory-mapped
address space. The V86 monitor may control memory-mapped I/O by any of
these means:
þ Assign the memory-mapped page to appropriate physical addresses.
Different tasks may have different physical addresses, thereby
preventing the tasks from interfering with each other.
þ Cause a trap to the monitor by forcing a page fault on the
memory-mapped page. Read-only pages trap writes. Not-present pages trap
both reads and writes.
Intervention for every I/O might be excessive for some kinds of I/O
devices. A page fault can still be used in this case to cause intervention
on the first I/O operation. The monitor can then at least make sure that the
task has exclusive access to the device. Then the monitor can change the
page status to present and read/write, allowing subsequent I/O to proceed at
full speed.
15.5.3 Special I/O Buffers
Buffers of intelligent controllers (for example, a bit-mapped graphics
buffer) can also be virtualized via page mapping. The linear space for the
buffer can be mapped to a different physical space for each virtual 8086
task. The V86 monitor can then assume responsibility for spooling the data
or assigning the virtual buffer to the real buffer at appropriate times.
15.6 Differences From 8086
In general, V86 mode will correctly execute software designed for the 8086,
8088, 80186, and 80188. Following is a list of the minor differences between
8086 execution on the 80386 and on an 8086.
1. Instruction clock counts.
The 80386 takes fewer clocks for most instructions than the
8086/8088. The areas most likely to be affected are:
þ Delays required by I/O devices between I/O operations.
þ Assumed delays with 8086/8088 operating in parallel with an 8087.
2. Divide exceptions point to the DIV instruction.
Divide exceptions on the 80386 always leave the saved CS:IP value
pointing to the instruction that failed. On the 8086/8088, the CS:IP
value points to the next instruction.
3. Undefined 8086/8088 opcodes.
Opcodes that were not defined for the 8086/8088 will cause exception
6 or will execute one of the new instructions defined for the 80386.
4. Value written by PUSH SP.
The 80386 pushes a different value on the stack for PUSH SP than the
8086/8088. The 80386 pushes the value of SP before SP is incremented
as part of the push operation; the 8086/8088 pushes the value of SP
after it is incremented. If the value pushed is important, replace
PUSH SP instructions with the following three instructions:
PUSH BP
MOV BP, SP
XCHG BP, [BP]
This code functions as the 8086/8088 PUSH SP instruction on the
80386.
5. Shift or rotate by more than 31 bits.
The 80386 masks all shift and rotate counts to the low-order five
bits. This MOD 32 operation limits the count to a maximum of 31 bits,
thereby limiting the time that interrupt response is delayed while
the instruction is executing.
6. Redundant prefixes.
The 80386 sets a limit of 15 bytes on instruction length. The only
way to violate this limit is by putting redundant prefixes before an
instruction. Exception 13 occurs if the limit on instruction length
is violated. The 8086/8088 has no instruction length limit.
7. Operand crossing offset 0 or 65,535.
On the 8086, an attempt to access a memory operand that crosses
offset 65,535 (e.g., MOV a word to offset 65,535) or offset 0 (e.g.,
PUSH a word when SP = 1) causes the offset to wrap around modulo
65,536. The 80386 raises an exception in these casesÄÄexception 13 if
the segment is a data segment (i.e., if CS, DS, ES, FS, or GS is
being used to address the segment), exception 12 if the segment is a
stack segment (i.e., if SS is being used).
8. Sequential execution across offset 65,535.
On the 8086, if sequential execution of instructions proceeds past
offset 65,535, the processor fetches the next instruction byte from
offset 0 of the same segment. On the 80386, the processor raises
exception 13 in such a case.
9. LOCK is restricted to certain instructions.
The LOCK prefix and its corresponding output signal should only be
used to prevent other bus masters from interrupting a data movement
operation. The 80386 always asserts the LOCK signal during an XCHG
instruction with memory (even if the LOCK prefix is not used). LOCK
may only be used with the following 80386 instructions when they
update memory: BTS, BTR, BTC, XCHG, ADD, ADC, SUB, SBB, INC, DEC,
AND, OR, XOR, NOT, and NEG. An undefined-opcode exception (interrupt
6) results from using LOCK before any other instruction.
10. Single-stepping external interrupt handlers.
The priority of the 80386 single-step exception is different from
that of the 8086/8088. The change prevents an external interrupt
handler from being single-stepped if the interrupt occurs while a
program is being single-stepped. The 80386 single-step exception has
higher priority that any external interrupt. The 80386 will still
single-step through an interrupt handler invoked by the INT
instructions or by an exception.
11. IDIV exceptions for quotients of 80H or 8000H.
The 80386 can generate the largest negative number as a quotient for
the IDIV instruction. The 8086/8088 causes exception zero instead.
12. Flags in stack.
The setting of the flags stored by PUSHF, by interrupts, and by
exceptions is different from that stored by the 8086 in bit positions
12 through 15. On the 8086 these bits are stored as ones, but in V86
mode bit 15 is always zero, and bits 14 through 12 reflect the last
value loaded into them.
13. NMI interrupting NMI handlers.
After an NMI is recognized on the 80386, the NMI interrupt is masked
until an IRET instruction is executed.
14. Coprocessor errors vector to interrupt 16.
Any 80386 system with a coprocessor must use interrupt vector 16 for
the coprocessor error exception. If an 8086/8088 system uses another
vector for the 8087 interrupt, both vectors should point to the
coprocessor-error exception handler.
15. Numeric exception handlers should allow prefixes.
On the 80386, the value of CS:IP saved for coprocessor exceptions
points at any prefixes before an ESC instruction. On 8086/8088
systems, the saved CS:IP points to the ESC instruction itself.
16. Coprocessor does not use interrupt controller.
The coprocessor error signal to the 80386 does not pass through an
interrupt controller (an 8087 INT signal does). Some instructions in
a coprocessor error handler may need to be deleted if they deal with
the interrupt controller.
15.7 Differences From 80286 Real-Address Mode
The 80286 processor implements the bus lock function differently than the
80386. This fact may or may not be apparent to 8086 programs, depending on
how the V86 monitor handles the LOCK prefix. LOCKed instructions are
sensitive to IOPL; therefore, software designers can choose to emulate its
function. If, however, 8086 programs are allowed to execute LOCK directly,
programs that use forms of memory locking specific to the 8086 may not
execute properly when transported to a specific application of the 80386.
The LOCK prefix and its corresponding output signal should only be used to
prevent other bus masters from interrupting a data movement operation. LOCK
may only be used with the following 80386 instructions when they modify
memory. An undefined-opcode exception results from using LOCK before any
other instruction.
þ Bit test and change: BTS, BTR, BTC.
þ Exchange: XCHG.
þ One-operand arithmetic and logical: INC, DEC, NOT, and NEG.
þ Two-operand arithmetic and logical: ADD, ADC, SUB, SBB, AND, OR, XOR.
A locked instruction is guaranteed to lock only the area of memory defined
by the destination operand, but may lock a larger memory area. For example,
typical 8086 and 80286 configurations lock the entire physical memory space.
With the 80386, the defined area of memory is guaranteed to be locked
against access by a processor executing a locked instruction on exactly the
same memory area, i.e., an operand with identical starting address and
identical length.
Chapter 16 Mixing 16-Bit and 32 Bit Code
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
The 80386 running in protected mode is a 32-bit microprocessor, but it is
designed to support 16-bit processing at three levels:
1. Executing 8086/80286 16-bit programs efficiently with complete
compatibility.
2. Mixing 16-bit modules with 32-bit modules.
3. Mixing 16-bit and 32-bit addresses and operands within one module.
The first level of support for 16-bit programs has already been discussed
in Chapter 13, Chapter 14, and Chapter 15. This chapter shows how 16-bit
and 32-bit modules can cooperate with one another, and how one module can
utilize both 16-bit and 32-bit operands and addressing.
The 80386 functions most efficiently when it is possible to distinguish
between pure 16-bit modules and pure 32-bit modules. A pure 16-bit module
has these characteristics:
þ All segments occupy 64 Kilobytes or less.
þ Data items are either 8 bits or 16 bits wide.
þ Pointers to code and data have 16-bit offsets.
þ Control is transferred only among 16-bit segments.
A pure 32-bit module has these characteristics:
þ Segments may occupy more than 64 Kilobytes (zero bytes to 4
gigabytes).
þ Data items are either 8 bits or 32 bits wide.
þ Pointers to code and data have 32-bit offsets.
þ Control is transferred only among 32-bit segments.
Pure 16-bit modules do exist; they are the modules designed for 16-bit
microprocessors. Pure 32-bit modules may exist in new programs designed
explicitly for the 80386. However, as systems designers move applications
from 16-bit processors to the 32-bit 80386, it will not always be possible
to maintain these ideals of pure 16-bit or 32-bit modules. It may be
expedient to execute old 16-bit modules in a new 32-bit environment without
making source-code changes to the old modules if any of the following
conditions is true:
þ Modules will be converted one-by-one from 16-bit environments to
32-bit environments.
þ Older, 16-bit compilers and software-development tools will be
utilized in the new32-bit operating environment until new 32-bit
versions can be created.
þ The source code of 16-bit modules is not available for modification.
þ The specific data structures used by a given module inherently utilize
16-bit words.
þ The native word size of the source language is 16 bits.
On the 80386, 16-bit modules can be mixed with 32-bit modules. To design a
system that mixes 16- and 32-bit code requires an understanding of the
mechanisms that the 80386 uses to invoke and control its 32-bit and 16-bit
features.
16.1 How the 80386 Implements 16-Bit and 32-Bit Features
The features of the architecture that permit the 80386 to work equally well
with 32-bit and 16-bit address and operand sizes include:
þ The D-bit (default bit) of code-segment descriptors, which determines
the default choice of operand-size and address-size for the
instructions of a code segment. (In real-address mode and V86 mode,
which do not use descriptors, the default is 16 bits.) A code segment
whose D-bit is set is known as a USE32 segment; a code segment whose
D-bit is zero is a USE16 segment. The D-bit eliminates the need to
encode the operand size and address size in instructions when all
instructions use operands and effective addresses of the same size.
þ Instruction prefixes that explicitly override the default choice of
operand size and address size (available in protected mode as well as
in real-address mode and V86 mode).
þ Separate 32-bit and 16-bit gates for intersegment control transfers
(including call gates, interrupt gates, and trap gates). The operand
size for the control transfer is determined by the type of gate, not by
the D-bit or prefix of the transfer instruction.
þ Registers that can be used both for 32-bit and 16-bit operands and
effective-address calculations.
þ The B-bit (big bit) of data-segment descriptors, which determines the
size of stack pointer (32-bit ESP or 16-bit SP) used by the CPU for
implicit stack references.
16.2 Mixing 32-Bit and 16-Bit Operations
The 80386 has two instruction prefixes that allow mixing of 32-bit and
16-bit operations within one segment:
þ The operand-size prefix (66H)
þ The address-size prefix (67H)
These prefixes reverse the default size selected by the D-bit. For example,
the processor can interpret the word-move instruction MOV mem, reg in any of
four ways:
þ In a USE32 segment:
1. Normally moves 32 bits from a 32-bit register to a 32-bit
effective address in memory.
2. If preceded by an operand-size prefix, moves 16 bits from a 16-bit
register to 32-bit effective address in memory.
3. If preceded by an address-size prefix, moves 32 bits from a 32-bit
register to a16-bit effective address in memory.
4. If preceded by both an address-size prefix and an operand-size
prefix, moves 16 bits from a 16-bit register to a 16-bit effective
address in memory.
þ In a USE16 segment:
1. Normally moves 16 bits from a 16-bit register to a 16-bit
effective address in memory.
2. If preceded by an operand-size prefix, moves 32 bits from a 32-bit
register to 16-bit effective address in memory.
3. If preceded by an address-size prefix, moves 16 bits from a 16-bit
register to a32-bit effective address in memory.
4. If preceded by both an address-size prefix and an operand-size
prefix, moves 32 bits from a 32-bit register to a 32-bit effective
address in memory.
These examples illustrate that any instruction can generate any combination
of operand size and address size regardless of whether the instruction is in
a USE16 or USE32 segment. The choice of the USE16 or USE32 attribute for a
code segment is based upon these criteria:
1. The need to address instructions or data in segments that are larger
than 64 Kilobytes.
2. The predominant size of operands.
3. The addressing modes desired. (Refer to Chapter 17 for an explanation
of the additional addressing modes that are available when 32-bit
addressing is used.)
Choosing a setting of the D-bit that is contrary to the predominant size of
operands requires the generation of an excessive number of operand-size
prefixes.
16.3 Sharing Data Segments Among Mixed Code Segments
Because the choice of operand size and address size is defined in code
segments and their descriptors, data segments can be shared freely among
both USE16 and USE32 code segments. The only limitation is the one imposed
by pointers with 16-bit offsets, which can only point to the first 64
Kilobytes of a segment. When a data segment that contains more than 64
Kilobytes is to be shared among USE32 and USE16 segments, the data that is
to be accessed by the USE16 segments must be located within the first 64
Kilobytes.
A stack that spans addresses less than 64K can be shared by both USE16 and
USE32 code segments. This class of stacks includes:
þ Stacks in expand-up segments with G=0 and B=0.
þ Stacks in expand-down segments with G=0 and B=0.
þ Stacks in expand-up segments with G=1 and B=0, in which the stack is
contained completely within the lower 64 Kilobytes. (Offsets greater
than 64K can be used for data, other than the stack, that is not
shared.)
The B-bit of a stack segment cannot, in general, be used to change the size
of stack used by a USE16 code segment. The size of stack pointer used by the
processor for implicit stack references is controlled by the B-bit of the
data-segment descriptor for the stack. Implicit references are those caused
by interrupts, exceptions, and instructions such as PUSH, POP, CALL, and
RET. One might be tempted, therefore, to try to increase beyond 64K the
size of the stack used by 16-bit code simply by supplying a larger stack
segment with the B-bit set. However, the B-bit does not control explicit
stack references, such as accesses to parameters or local variables. A USE16
code segment can utilize a "big" stack only if the code is modified so that
all explicit references to the stack are preceded by the address-size
prefix, causing those references to use 32-bit addressing.
In big, expand-down segments (B=1, G=1, and E=1), all offsets are greater
than 64K, therefore USE16 code cannot utilize such a stack segment unless
the code segment is modified to employ 32-bit addressing. (Refer to Chapter
6 for a review of the B, G, and E bits.)
16.4 Transferring Control Among Mixed Code Segments
When transferring control among procedures in USE16 and USE32 code
segments, programmers must be aware of three points:
þ Addressing limitations imposed by pointers with 16-bit offsets.
þ Matching of operand-size attribute in effect for the CALL/RET pair and
theInterrupt/IRET pair so as to manage the stack correctly.
þ Translation of parameters, especially pointer parameters.
Clearly, 16-bit effective addresses cannot be used to address data or code
located beyond 64K in a 32-bit segment, nor can large 32-bit parameters be
squeezed into a 16-bit word; however, except for these obvious limits, most
interfacing problems between 16-bit and 32-bit modules can be solved. Some
solutions involve inserting interface procedures between the procedures in
question.
16.4.1 Size of Code-Segment Pointer
For control-transfer instructions that use a pointer to identify the next
instruction (i.e., those that do not use gates), the size of the offset
portion of the pointer is determined by the operand-size attribute. The
implications of the use of two different sizes of code-segment pointer are:
þ JMP, CALL, or RET from 32-bit segment to 16-bit segment is always
possible using a 32-bit operand size.
þ JMP, CALL, or RET from 16-bit segment using a 16-bit operand size
cannot address the target in a 32-bit segment if the address of the
target is greater than 64K.
An interface procedure can enable transfers from USE16 segments to 32-bit
addresses beyond 64K without requiring modifications any more extensive than
relinking or rebinding the old programs. The requirements for such an
interface procedure are discussed later in this chapter.
16.4.2 Stack Management for Control Transfers
Because stack management is different for 16-bit CALL/RET than for 32-bit
CALL/RET, the operand size of RET must match that of CALL. (Refer to Figure
16-1.) A 16-bit CALL pushes the 16-bit IP and (for calls between privilege
levels) the 16-bit SP register. The corresponding RET must also use a 16-bit
operand size to POP these 16-bit values from the stack into the 16-bit
registers. A 32-bit CALL pushes the 32-bit EIP and (for interlevel calls)
the 32-bit ESP register. The corresponding RET must also use a 32-bit
operand size to POP these 32-bit values from the stack into the 32-bit
registers. If the two halves of a CALL/RET pair do not have matching operand
sizes, the stack will not be managed correctly and the values of the
instruction pointer and stack pointer will not be restored to correct
values.
When the CALL and its corresponding RET are in segments that have D-bits
with the same values (i.e., both have 32-bit defaults or both have 16-bit
defaults), there is no problem. When the CALL and its corresponding RET are
in segments that have different D-bit values, however, programmers (or
program development software) must ensure that the CALL and RET match.
There are three ways to cause a 16-bit procedure to execute a 32-bit call:
1. Use a 16-bit call to a 32-bit interface procedure that then uses a
32-bit call to invoke the intended target.
2. Bind the 16-bit call to a 32-bit call gate.
3. Modify the 16-bit procedure, inserting an operand-size prefix before
the call, thereby changing it to a 32-bit call.
Likewise, there are three ways to cause a 32-bit procedure to execute a
16-bit call:
1. Use a 32-bit call to a 32-bit interface procedure that then uses a
16-bit call to invoke the intended target.
2. Bind the 32-bit call to a 16-bit call gate.
3. Modify the 32-bit procedure, inserting an operand-size prefix before
the call, thereby changing it to a 16-bit call. (Be certain that the
return offset does not exceed 64K.)
Programmers can utilize any of the preceding methods to make a CALL in a
USE16 segment match the corresponding RET in a USE32 segment, or to make a
CALL in a USE32 segment match the corresponding RET in a USE16 segment.
Figure 16-1. Stack after Far 16-Bit and 32-Bit Calls
WITHOUT PRIVILEGE TRANSITION
AFTER 16-BIT CALL AFTER 32-BIT CALL
31 0 31 0
D O º º º º
I F ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
R º±±±±±±±±±±±±±±±º º±±±±±±±±±±±±±±±º
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
C X º PARM2 ³ PARM1 º º PARM2 º
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
I A º CS ³ IP ºÄÄSP º PARM1 º
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
N S º º º±±±±±±±³ CS º
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
³ O º º º EIP ºÄÄESP
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
³ º º º º
    
WITH PRIVILEGE TRANSITION
AFTER 16-BIT CALL AFTER 32-BIT CALL
D O 31 0 31 0
I F ÉÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ» ÉÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ»
R º SS ³ SP º º±±±±±±±³ SS º
E E ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
C X º PARM2 ³ PARM1 º º ESP º
T P ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
I A º CS ³ IP ºÄÄSP º PARM2 º
O N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
N S º º º PARM1 º
I ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
³ O º º º±±±±±±±³ CS º
³ N ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
³ º º º EIP ºÄÄESP
 ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹ ÌÍÍÍÍÍÍÍØÍÍÍÍÍÍ͹
º º º º
   
16.4.2.1 Controlling the Operand-Size for a Call
When the selector of the pointer referenced by a CALL instruction selects a
segment descriptor, the operand-size attribute in effect for the CALL
instruction is determined by the D-bit in the segment descriptor and by any
operand-size instruction prefix.
When the selector of the pointer referenced by a CALL instruction selects a
gate descriptor, the type of call is determined by the type of call gate. A
call via an 80286 call gate (descriptor type 4) always has a 16-bit
operand-size attribute; a call via an 80386 call gate (descriptor type 12)
always has a 32-bit operand-size attribute. The offset of the target
procedure is taken from the gate descriptor; therefore, even a 16-bit
procedure can call a procedure that is located more than 64 kilobytes from
the base of a 32-bit segment, because a 32-bit call gate contains a 32-bit
target offset.
An unmodified 16-bit code segment that has run successfully on an 8086 or
real-mode 80286 will always have a D-bit of zero and will not use
operand-size override prefixes; therefore, it will always execute 16-bit
versions of CALL. The only modification needed to make a16-bit procedure
effect a 32-bit call is to relink the call to an 80386 call gate.
16.4.2.2 Changing Size of Call
When adding 32-bit gates to 16-bit procedures, it is important to consider
the number of parameters. The count field of the gate descriptor specifies
the size of the parameter string to copy from the current stack to the stack
of the more privileged procedure. The count field of a 16-bit gate specifies
the number of words to be copied, whereas the count field of a 32-bit gate
specifies the number of doublewords to be copied; therefore, the 16-bit
procedure must use an even number of words as parameters.
16.4.3 Interrupt Control Transfers
With a control transfer due to an interrupt or exception, a gate is always
involved. The operand-size attribute for the interrupt is determined by the
type of IDT gate.
A 386 interrupt or trap gate (descriptor type 14 or 15) to a 32-bit
interrupt procedure can be used to interrupt either 32-bit or 16-bit
procedures. However, it is not generally feasible to permit an interrupt or
exception to invoke a 16-bit handler procedure when 32-bit code is
executing, because a 16-bit interrupt procedure has a return offset of only
16-bits on its stack. If the 32-bit procedure is executing at an address
greater than 64K, the 16-bit interrupt procedure cannot return correctly.
16.4.4 Parameter Translation
When segment offsets or pointers (which contain segment offsets) are passed
as parameters between 16-bit and 32-bit procedures, some translation is
required. Clearly, if a 32-bit procedure passes a pointer to data located
beyond 64K to a 16-bit procedure, the 16-bit procedure cannot utilize it.
Beyond this natural limitation, an interface procedure can perform any
format conversion between 32-bit and 16-bit pointers that may be needed.
Parameters passed by value between 32-bit and 16-bit code may also require
translation between 32-bit and 16-bit formats. Such translation requirements
are application dependent. Systems designers should take care to limit the
range of values passed so that such translations are possible.
16.4.5 The Interface Procedure
Interposing an interface procedure between 32-bit and 16-bit procedures can
be the solution to any of several interface requirements:
þ Allowing procedures in 16-bit segments to transfer control to
instructions located beyond 64K in 32-bit segments.
þ Matching of operand size for CALL/RET.
þ Parameter translation.
Interface procedures between USE32 and USE16 segments can be constructed
with these properties:
þ The procedures reside in a code segment whose D-bit is set, indicating
a default operand size of 32-bits.
þ All entry points that may be called by 16-bit procedures have offsets
that are actually less than 64K.
þ All points to which called 16-bit procedures may return also lie
within 64K.
The interface procedures do little more than call corresponding procedures
in other segments. There may be two kinds of procedures:
þ Those that are called by 16-bit procedures and call 32-bit procedures.
These interface procedures are called by 16-bit CALLs and use the
operand-size prefix before RET instructions to cause a 16-bit RET.
CALLs to 32-bit segments are 32-bit calls (by default, because the
D-bit is set), and the 32-bit code returns with 32-bit RET
instructions.
þ Those that are called by 32-bit procedures and call 16-bit procedures.
These interface procedures are called by 32-bit CALL instructions, and
return with 32-bit RET instructions (by default, because the D-bit is
set). CALLs to 16-bit procedures use the operand-size prefix;
procedures in the 16-bit code return with 16-bit RET instructions.
PART IV INSTRUCTION SET
Chapter 17 80386 Instruction Set
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
This chapter presents instructions for the 80386 in alphabetical order. For
each instruction, the forms are given for each operand combination,
including object code produced, operands required, execution time, and a
description. For each instruction, there is an operational description and a
summary of exceptions generated.
17.1 Operand-Size and Address-Size Attributes
When executing an instruction, the 80386 can address memory using either 16
or 32-bit addresses. Consequently, each instruction that uses memory
addresses has associated with it an address-size attribute of either 16 or
32 bits. 16-bit addresses imply both the use of a 16-bit displacement in
the instruction and the generation of a 16-bit address offset (segment
relative address) as the result of the effective address calculation.
32-bit addresses imply the use of a 32-bit displacement and the generation
of a 32-bit address offset. Similarly, an instruction that accesses words
(16 bits) or doublewords (32 bits) has an operand-size attribute of either
16 or 32 bits.
The attributes are determined by a combination of defaults, instruction
prefixes, and (for programs executing in protected mode) size-specification
bits in segment descriptors.
17.1.1 Default Segment Attribute
For programs executed in protected mode, the D-bit in executable-segment
descriptors determines the default attribute for both address size and
operand size. These default attributes apply to the execution of all
instructions in the segment. A value of zero in the D-bit sets the default
address size and operand size to 16 bits; a value of one, to 32 bits.
Programs that execute in real mode or virtual-8086 mode have 16-bit
addresses and operands by default.
17.1.2 Operand-Size and Address-Size Instruction Prefixes
The internal encoding of an instruction can include two byte-long prefixes:
the address-size prefix, 67H, and the operand-size prefix, 66H. (A later
section, "Instruction Format," shows the position of the prefixes in an
instruction's encoding.) These prefixes override the default segment
attributes for the instruction that follows. Table 17-1 shows the effect of
each possible combination of defaults and overrides.
17.1.3 Address-Size Attribute for Stack
Instructions that use the stack implicitly (for example: POP EAX also have
a stack address-size attribute of either 16 or 32 bits. Instructions with a
stack address-size attribute of 16 use the 16-bit SP stack pointer register;
instructions with a stack address-size attribute of 32 bits use the 32-bit
ESP register to form the address of the top of the stack.
The stack address-size attribute is controlled by the B-bit of the
data-segment descriptor in the SS register. A value of zero in the B-bit
selects a stack address-size attribute of 16; a value of one selects a stack
address-size attribute of 32.
Table 17-1. Effective Size Attributes
Segment Default D = ... 0 0 0 0 1 1 1 1
Operand-Size Prefix 66H N N Y Y N N Y Y
Address-Size Prefix 67H N Y N Y N Y N Y
Effective Operand Size 16 16 32 32 32 32 16 16
Effective Address Size 16 32 16 32 32 16 32 16
Y = Yes, this instruction prefix is present
N = No, this instruction prefix is not present
17.2 Instruction Format
All instruction encodings are subsets of the general instruction format
shown in Figure 17-1. Instructions consist of optional instruction
prefixes, one or two primary opcode bytes, possibly an address specifier
consisting of the ModR/M byte and the SIB (Scale Index Base) byte, a
displacement, if required, and an immediate data field, if required.
Smaller encoding fields can be defined within the primary opcode or
opcodes. These fields define the direction of the operation, the size of the
displacements, the register encoding, or sign extension; encoding fields
vary depending on the class of operation.
Most instructions that can refer to an operand in memory have an addressing
form byte following the primary opcode byte(s). This byte, called the ModR/M
byte, specifies the address form to be used. Certain encodings of the ModR/M
byte indicate a second addressing byte, the SIB (Scale Index Base) byte,
which follows the ModR/M byte and is required to fully specify the
addressing form.
Addressing forms can include a displacement immediately following either
the ModR/M or SIB byte. If a displacement is present, it can be 8-, 16- or
32-bits.
If the instruction specifies an immediate operand, the immediate operand
always follows any displacement bytes. The immediate operand, if specified,
is always the last field of the instruction.
The following are the allowable instruction prefix codes:
F3H REP prefix (used only with string instructions)
F3H REPE/REPZ prefix (used only with string instructions
F2H REPNE/REPNZ prefix (used only with string instructions)
F0H LOCK prefix
The following are the segment override prefixes:
2EH CS segment override prefix
36H SS segment override prefix
3EH DS segment override prefix
26H ES segment override prefix
64H FS segment override prefix
65H GS segment override prefix
66H Operand-size override
67H Address-size override
Figure 17-1. 80386 Instruction Format
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º INSTRUCTION º ADDRESS- º OPERAND- º SEGMENT º
º PREFIX º SIZE PREFIX º SIZE PREFIX º OVERRIDE º
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
º 0 OR 1 0 OR 1 0 OR 1 0 OR 1 º
ÇÄ Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä¶
º NUMBER OF BYTES º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
ÉÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º OPCODE º MODR/M º SIB º DISPLACEMENT º IMMEDIATE º
º º º º º º
ÌÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍ͹
º 1 OR 2 0 OR 1 0 OR 1 0,1,2 OR 4 0,1,2 OR 4 º
ÇÄ Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä Ä¶
º NUMBER OF BYTES º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
17.2.1 ModR/M and SIB Bytes
The ModR/M and SIB bytes follow the opcode byte(s) in many of the 80386
instructions. They contain the following information:
þ The indexing type or register number to be used in the instruction
þ The register to be used, or more information to select the instruction
þ The base, index, and scale information
The ModR/M byte contains three fields of information:
þ The mod field, which occupies the two most significant bits of the
byte, combines with the r/m field to form 32 possible values: eight
registers and 24 indexing modes
þ The reg field, which occupies the next three bits following the mod
field, specifies either a register number or three more bits of opcode
information. The meaning of the reg field is determined by the first
(opcode) byte of the instruction.
þ The r/m field, which occupies the three least significant bits of the
byte, can specify a register as the location of an operand, or can form
part of the addressing-mode encoding in combination with the field as
described above
The based indexed and scaled indexed forms of 32-bit addressing require the
SIB byte. The presence of the SIB byte is indicated by certain encodings of
the ModR/M byte. The SIB byte then includes the following fields:
þ The ss field, which occupies the two most significant bits of the
byte, specifies the scale factor
þ The index field, which occupies the next three bits following the ss
field and specifies the register number of the index register
þ The base field, which occupies the three least significant bits of the
byte, specifies the register number of the base register
Figure 17-2 shows the formats of the ModR/M and SIB bytes.
The values and the corresponding addressing forms of the ModR/M and SIB
bytes are shown in Tables 17-2, 17-3, and 17-4. The 16-bit addressing
forms specified by the ModR/M byte are in Table 17-2. The 32-bit addressing
forms specified by ModR/M are in Table 17-3. Table 17-4 shows the 32-bit
addressing forms specified by the SIB byte
Figure 17-2. ModR/M and SIB Byte Formats
MODR/M BYTE
7 6 5 4 3 2 1 0
ÉÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º MOD º REG/OPCODE º R/M º
ÈÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍͼ
SIB (SCALE INDEX BASE) BYTE
7 6 5 4 3 2 1 0
ÉÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º SS º INDEX º BASE º
ÈÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍͼ
Table 17-2. 16-Bit Addressing Forms with the ModR/M Byte
r8(/r) AL CL DL BL AH CH DH BH
r16(/r) AX CX DX BX SP BP SI DI
r32(/r) EAX ECX EDX EBX ESP EBP ESI EDI
/digit (Opcode) 0 1 2 3 4 5 6 7
REG = 000 001 010 011 100 101 110 111
Effective
ÚÄÄÄAddress
disp8 denotes an 8-bit displacement following the ModR/M byte, to be
sign-extended and added to the index. disp16 denotes a 16-bit displacement
following the ModR/M byte, to be added to the index. Default segment
register is SS for the effective addresses containing a BP index, DS for
other effective addresses.ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄModR/M Values in
HexadecimalÄÄÄÄÄÄÄÄ¿
[BX + SI] 000 00 08 10 18 20 28 30 38
[BX + DI] 001 01 09 11 19 21 29 31 39
[BP + SI] 010 02 0A 12 1A 22 2A 32 3A
[BP + DI] 011 03 0B 13 1B 23 2B 33 3B
[SI] 00 100 04 0C 14 1C 24 2C 34 3C
[DI] 101 05 0D 15 1D 25 2D 35 3D
disp16 110 06 0E 16 1E 26 2E 36 3E
[BX] 111 07 0F 17 1F 27 2F 37 3F
[BX+SI]+disp8 000 40 48 50 58 60 68 70 78
[BX+DI]+disp8 001 41 49 51 59 61 69 71 79
[BP+SI]+disp8 010 42 4A 52 5A 62 6A 72 7A
[BP+DI]+disp8 011 43 4B 53 5B 63 6B 73 7B
[SI]+disp8 01 100 44 4C 54 5C 64 6C 74 7C
[DI]+disp8 101 45 4D 55 5D 65 6D 75 7D
[BP]+disp8 110 46 4E 56 5E 66 6E 76 7E
[BX]+disp8 111 47 4F 57 5F 67 6F 77 7F
[BX+SI]+disp16 000 80 88 90 98 A0 A8 B0 B8
[BX+DI]+disp16 001 81 89 91 99 A1 A9 B1 B9
[BX+SI]+disp16 010 82 8A 92 9A A2 AA B2 BA
[BX+DI]+disp16 011 83 8B 93 9B A3 AB B3 BB
[SI]+disp16 10 100 84 8C 94 9C A4 AC B4 BC
[DI]+disp16 101 85 8D 95 9D A5 AD B5 BD
[BP]+disp16 110 86 8E 96 9E A6 AE B6 BE
[BX]+disp16 111 87 8F 97 9F A7 AF B7 BF
EAX/AX/AL 000 C0 C8 D0 D8 E0 E8 F0 F8
ECX/CX/CL 001 C1 C9 D1 D9 E1 E9 F1 F9
EDX/DX/DL 010 C2 CA D2 DA E2 EA F2 FA
EBX/BX/BL 011 C3 CB D3 DB E3 EB F3 FB
ESP/SP/AH 11 100 C4 CC D4 DC E4 EC F4 FC
EBP/BP/CH 101 C5 CD D5 DD E5 ED F5 FD
ESI/SI/DH 110 C6 CE D6 DE E6 EE F6 FE
EDI/DI/BH 111 C7 CF D7 DF E7 EF F7 FF
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
disp8 denotes an 8-bit displacement following the ModR/M byte, to be
sign-extended and added to the index. disp16 denotes a 16-bit displacement
following the ModR/M byte, to be added to the index. Default segment
register is SS for the effective addresses containing a BP index, DS for
other effective addresses.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Table 17-3. 32-Bit Addressing Forms with the ModR/M Byte
r8(/r) AL CL DL BL AH CH DH BH
r16(/r) AX CX DX BX SP BP SI DI
r32(/r) EAX ECX EDX EBX ESP EBP ESI EDI
/digit (Opcode) 0 1 2 3 4 5 6 7
REG = 000 001 010 011 100 101 110 111
Effective
ÚÄÄÄAddress
[--] [--] means a SIB follows the ModR/M byte. disp8 denotes an 8-bit
displacement following the SIB byte, to be sign-extended and added to the
index. disp32 denotes a 32-bit displacement following the ModR/M byte, to
be added to the index.ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄÄModR/M Values in
HexadecimalÄÄÄÄÄÄÄ¿
[EAX] 000 00 08 10 18 20 28 30 38
[ECX] 001 01 09 11 19 21 29 31 39
[EDX] 010 02 0A 12 1A 22 2A 32 3A
[EBX] 011 03 0B 13 1B 23 2B 33 3B
[--] [--] 00 100 04 0C 14 1C 24 2C 34 3C
disp32 101 05 0D 15 1D 25 2D 35 3D
[ESI] 110 06 0E 16 1E 26 2E 36 3E
[EDI] 111 07 0F 17 1F 27 2F 37 3F
disp8[EAX] 000 40 48 50 58 60 68 70 78
disp8[ECX] 001 41 49 51 59 61 69 71 79
disp8[EDX] 010 42 4A 52 5A 62 6A 72 7A
disp8[EPX]; 011 43 4B 53 5B 63 6B 73 7B
disp8[--] [--] 01 100 44 4C 54 5C 64 6C 74 7C
disp8[ebp] 101 45 4D 55 5D 65 6D 75 7D
disp8[ESI] 110 46 4E 56 5E 66 6E 76 7E
disp8[EDI] 111 47 4F 57 5F 67 6F 77 7F
disp32[EAX] 000 80 88 90 98 A0 A8 B0 B8
disp32[ECX] 001 81 89 91 99 A1 A9 B1 B9
disp32[EDX] 010 82 8A 92 9A A2 AA B2 BA
disp32[EBX] 011 83 8B 93 9B A3 AB B3 BB
disp32[--] [--] 10 100 84 8C 94 9C A4 AC B4 BC
disp32[EBP] 101 85 8D 95 9D A5 AD B5 BD
disp32[ESI] 110 86 8E 96 9E A6 AE B6 BE
disp32[EDI] 111 87 8F 97 9F A7 AF B7 BF
EAX/AX/AL 000 C0 C8 D0 D8 E0 E8 F0 F8
ECX/CX/CL 001 C1 C9 D1 D9 E1 E9 F1 F9
EDX/DX/DL 010 C2 CA D2 DA E2 EA F2 FA
EBX/BX/BL 011 C3 CB D3 DB E3 EB F3 FB
ESP/SP/AH 11 100 C4 CC D4 DC E4 EC F4 FC
EBP/BP/CH 101 C5 CD D5 DD E5 ED F5 FD
ESI/SI/DH 110 C6 CE D6 DE E6 EE F6 FE
EDI/DI/BH 111 C7 CF D7 DF E7 EF F7 FF
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
[--] [--] means a SIB follows the ModR/M byte. disp8 denotes an 8-bit
displacement following the SIB byte, to be sign-extended and added to the
index. disp32 denotes a 32-bit displacement following the ModR/M byte, to
be added to the index.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Table 17-4. 32-Bit Addressing Forms with the SIB Byte
r32 EAX ECX EDX EBX ESP [*]
[*] means a disp32 with no base if MOD is 00, [ESP] otherwise. This provides
the following addressing modes:
disp32[index] (MOD=00)
disp8[EBP][index] (MOD=01)
disp32[EBP][index] (MOD=10) ESI EDI
Base = 0 1 2 3 4 5 6 7
Base = 000 001 010 011 100 101 110 111
ÚScaled Index
[*] means a disp32 with no base if MOD is 00, [ESP] otherwise. This provides
the following addressing modes:
disp32[index] (MOD=00)
disp8[EBP][index] (MOD=01)
disp32[EBP][index] (MOD=10)¿ÚSS Index¿ ÚÄÄÄÄÄÄÄÄModR/M Values in
HexadecimalÄÄÄÄÄÄÄÄ¿
[EAX] 000 00 01 02 03 04 05 06 07
[ECX] 001 08 09 0A 0B 0C 0D 0E 0F
[EDX] 010 10 11 12 13 14 15 16 17
[EBX] 011 18 19 1A 1B 1C 1D 1E 1F
none 00 100 20 21 22 23 24 25 26 27
[EBP] 101 28 29 2A 2B 2C 2D 2E 2F
[ESI] 110 30 31 32 33 34 35 36 37
[EDI] 111 38 39 3A 3B 3C 3D 3E 3F
[EAX*2] 000 40 41 42 43 44 45 46 47
[ECX*2] 001 48 49 4A 4B 4C 4D 4E 4F
[ECX*2] 010 50 51 52 53 54 55 56 57
[EBX*2] 011 58 59 5A 5B 5C 5D 5E 5F
none 01 100 60 61 62 63 64 65 66 67
[EBP*2] 101 68 69 6A 6B 6C 6D 6E 6F
[ESI*2] 110 70 71 72 73 74 75 76 77
[EDI*2] 111 78 79 7A 7B 7C 7D 7E 7F
[EAX*4] 000 80 81 82 83 84 85 86 87
[ECX*4] 001 88 89 8A 8B 8C 8D 8E 8F
[EDX*4] 010 90 91 92 93 94 95 96 97
[EBX*4] 011 98 89 9A 9B 9C 9D 9E 9F
none 10 100 A0 A1 A2 A3 A4 A5 A6 A7
[EBP*4] 101 A8 A9 AA AB AC AD AE AF
[ESI*4] 110 B0 B1 B2 B3 B4 B5 B6 B7
[EDI*4] 111 B8 B9 BA BB BC BD BE BF
[EAX*8] 000 C0 C1 C2 C3 C4 C5 C6 C7
[ECX*8] 001 C8 C9 CA CB CC CD CE CF
[EDX*8] 010 D0 D1 D2 D3 D4 D5 D6 D7
[EBX*8] 011 D8 D9 DA DB DC DD DE DF
none 11 100 E0 E1 E2 E3 E4 E5 E6 E7
[EBP*8] 101 E8 E9 EA EB EC ED EE EF
[ESI*8] 110 F0 F1 F2 F3 F4 F5 F6 F7
[EDI*8] 111 F8 F9 FA FB FC FD FE FF
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
[*] means a disp32 with no base if MOD is 00, [ESP] otherwise. This
provides the following addressing modes:
disp32[index] (MOD=00)
disp8[EBP][index] (MOD=01)
disp32[EBP][index] (MOD=10)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
17.2.2 How to Read the Instruction Set Pages
The following is an example of the format used for each 80386 instruction
description in this chapter:
CMC ÄÄ Complement Carry Flag
Opcode Instruction Clocks Description
F5 CMC 2 Complement carry flag
The above table is followed by paragraphs labelled "Operation,"
"Description," "Flags Affected," "Protected Mode Exceptions," "Real
Address Mode Exceptions," and, optionally, "Notes." The following sections
explain the notational conventions and abbreviations used in these
paragraphs of the instruction descriptions.
17.2.2.1 Opcode
The "Opcode" column gives the complete object code produced for each form
of the instruction. When possible, the codes are given as hexadecimal bytes,
in the same order in which they appear in memory. Definitions of entries
other than hexadecimal bytes are as follows:
/digit: (digit is between 0 and 7) indicates that the ModR/M byte of the
instruction uses only the r/m (register or memory) operand. The reg field
contains the digit that provides an extension to the instruction's opcode.
/r: indicates that the ModR/M byte of the instruction contains both a
register operand and an r/m operand.
cb, cw, cd, cp: a 1-byte (cb), 2-byte (cw), 4-byte (cd) or 6-byte (cp)
value following the opcode that is used to specify a code offset and
possibly a new value for the code segment register.
ib, iw, id: a 1-byte (ib), 2-byte (iw), or 4-byte (id) immediate operand to
the instruction that follows the opcode, ModR/M bytes or scale-indexing
bytes. The opcode determines if the operand is a signed value. All words and
doublewords are given with the low-order byte first.
+rb, +rw, +rd: a register code, from 0 through 7, added to the hexadecimal
byte given at the left of the plus sign to form a single opcode byte. The
codes areÄÄ
rb rw rd
AL = 0 AX = 0 EAX = 0
CL = 1 CX = 1 ECX = 1
DL = 2 DX = 2 EDX = 2
BL = 3 BX = 3 EBX = 3
AH = 4 SP = 4 ESP = 4
CH = 5 BP = 5 EBP = 5
DH = 6 SI = 6 ESI = 6
BH = 7 DI = 7 EDI = 7
17.2.2.2 Instruction
The "Instruction" column gives the syntax of the instruction statement as
it would appear in an ASM386 program. The following is a list of the symbols
used to represent operands in the instruction statements:
rel8: a relative address in the range from 128 bytes before the end of the
instruction to 127 bytes after the end of the instruction.
rel16, rel32: a relative address within the same code segment as the
instruction assembled. rel16 applies to instructions with an operand-size
attribute of 16 bits; rel32 applies to instructions with an operand-size
attribute of 32 bits.
ptr16:16, ptr16:32: a FAR pointer, typically in a code segment different
from that of the instruction. The notation 16:16 indicates that the value of
the pointer has two parts. The value to the right of the colon is a 16-bit
selector or value destined for the code segment register. The value to the
left corresponds to the offset within the destination segment. ptr16:16 is
used when the instruction's operand-size attribute is 16 bits; ptr16:32 is
used with the 32-bit attribute.
r8: one of the byte registers AL, CL, DL, BL, AH, CH, DH, or BH.
r16: one of the word registers AX, CX, DX, BX, SP, BP, SI, or DI.
r32: one of the doubleword registers EAX, ECX, EDX, EBX, ESP, EBP, ESI, or
EDI.
imm8: an immediate byte value. imm8 is a signed number between -128 and
+127 inclusive. For instructions in which imm8 is combined with a word or
doubleword operand, the immediate value is sign-extended to form a word or
doubleword. The upper byte of the word is filled with the topmost bit of the
immediate value.
imm16: an immediate word value used for instructions whose operand-size
attribute is 16 bits. This is a number between -32768 and +32767 inclusive.
imm32: an immediate doubleword value used for instructions whose
operand-size attribute is 32-bits. It allows the use of a number between
+2147483647 and -2147483648.
r/m8: a one-byte operand that is either the contents of a byte register
(AL, BL, CL, DL, AH, BH, CH, DH), or a byte from memory.
r/m16: a word register or memory operand used for instructions whose
operand-size attribute is 16 bits. The word registers are: AX, BX, CX, DX,
SP, BP, SI, DI. The contents of memory are found at the address provided by
the effective address computation.
r/m32: a doubleword register or memory operand used for instructions whose
operand-size attribute is 32-bits. The doubleword registers are: EAX, EBX,
ECX, EDX, ESP, EBP, ESI, EDI. The contents of memory are found at the
address provided by the effective address computation.
m8: a memory byte addressed by DS:SI or ES:DI (used only by string
instructions).
m16: a memory word addressed by DS:SI or ES:DI (used only by string
instructions).
m32: a memory doubleword addressed by DS:SI or ES:DI (used only by string
instructions).
m16:16, M16:32: a memory operand containing a far pointer composed of two
numbers. The number to the left of the colon corresponds to the pointer's
segment selector. The number to the right corresponds to its offset.
m16 & 32, m16 & 16, m32 & 32: a memory operand consisting of data item pairs
whose sizes are indicated on the left and the right side of the ampersand.
All memory addressing modes are allowed. m16 & 16 and m32 & 32 operands are
used by the BOUND instruction to provide an operand containing an upper and
lower bounds for array indices. m16 & 32 is used by LIDT and LGDT to
provide a word with which to load the limit field, and a doubleword with
which to load the base field of the corresponding Global and Interrupt
Descriptor Table Registers.
moffs8, moffs16, moffs32: (memory offset) a simple memory variable of type
BYTE, WORD, or DWORD used by some variants of the MOV instruction. The
actual address is given by a simple offset relative to the segment base. No
ModR/M byte is used in the instruction. The number shown with moffs
indicates its size, which is determined by the address-size attribute of the
instruction.
Sreg: a segment register. The segment register bit assignments are ES=0,
CS=1, SS=2, DS=3, FS=4, and GS=5.
17.2.2.3 Clocks
The "Clocks" column gives the number of clock cycles the instruction takes
to execute. The clock count calculations makes the following assumptions:
þ The instruction has been prefetched and decoded and is ready for
execution.
þ Bus cycles do not require wait states.
þ There are no local bus HOLD requests delaying processor access to the
bus.
þ No exceptions are detected during instruction execution.
þ Memory operands are aligned.
Clock counts for instructions that have an r/m (register or memory) operand
are separated by a slash. The count to the left is used for a register
operand; the count to the right is used for a memory operand.
The following symbols are used in the clock count specifications:
þ n, which represents a number of repetitions.
þ m, which represents the number of components in the next instruction
executed, where the entire displacement (if any) counts as one
component, the entire immediate data (if any) counts as one component,
and every other byte of the instruction and prefix(es) each counts as
one component.
þ pm=, a clock count that applies when the instruction executes in
Protected Mode. pm= is not given when the clock counts are the same for
Protected and Real Address Modes.
When an exception occurs during the execution of an instruction and the
exception handler is in another task, the instruction execution time is
increased by the number of clocks to effect a task switch. This parameter
depends on several factors:
þ The type of TSS used to represent the current task (386 TSS or 286
TSS).
þ The type of TSS used to represent the new task.
þ Whether the current task is in V86 mode.
þ Whether the new task is in V86 mode.
Table 17-5 summarizes the task switch times for exceptions.
Table 17-5. Task Switch Times for Exceptions
New Task
Old 386 TSS 286 TSS
Task VM = 0
386 VM = 0 309 282
TSS
386 VM = 1 314 231
TSS
286 307 282
TSS
17.2.2.4 Description
The "Description" column following the "Clocks" column briefly explains the
various forms of the instruction. The "Operation" and "Description" sections
contain more details of the instruction's operation.
17.2.2.5 Operation
The "Operation" section contains an algorithmic description of the
instruction which uses a notation similar to the Algol or Pascal language.
The algorithms are composed of the following elements:
Comments are enclosed within the symbol pairs "(*" and "*)".
Compound statements are enclosed between the keywords of the "if" statement
(IF, THEN, ELSE, FI) or of the "do" statement (DO, OD), or of the "case"
statement (CASE ... OF, ESAC).
A register name implies the contents of the register. A register name
enclosed in brackets implies the contents of the location whose address is
contained in that register. For example, ES:[DI] indicates the contents of
the location whose ES segment relative address is in register DI. [SI]
indicates the contents of the address contained in register SI relative to
SI's default segment (DS) or overridden segment.
Brackets also used for memory operands, where they mean that the contents
of the memory location is a segment-relative offset. For example, [SRC]
indicates that the contents of the source operand is a segment-relative
offset.
A  B; indicates that the value of B is assigned to A.
The symbols =, <>, ò, and ó are relational operators used to compare two
values, meaning equal, not equal, greater or equal, less or equal,
respectively. A relational expression such as A = B is TRUE if the value of
A is equal to B; otherwise it is FALSE.
The following identifiers are used in the algorithmic descriptions:
þ OperandSize represents the operand-size attribute of the instruction,
which is either 16 or 32 bits. AddressSize represents the address-size
attribute, which is either 16 or 32 bits. For example,
IF instruction = CMPSW
THEN OperandSize  16;
ELSE
IF instruction = CMPSD
THEN OperandSize  32;
FI;
FI;
indicates that the operand-size attribute depends on the form of the CMPS
instruction used. Refer to the explanation of address-size and operand-size
attributes at the beginning of this chapter for general guidelines on how
these attributes are determined.
þ StackAddrSize represents the stack address-size attribute associated
with the instruction, which has a value of 16 or 32 bits, as explained
earlier in the chapter.
þ SRC represents the source operand. When there are two operands, SRC is
the one on the right.
þ DEST represents the destination operand. When there are two operands,
DEST is the one on the left.
þ LeftSRC, RightSRC distinguishes between two operands when both are
source operands.
þ eSP represents either the SP register or the ESP register depending on
the setting of the B-bit for the current stack segment.
The following functions are used in the algorithmic descriptions:
þ Truncate to 16 bits(value) reduces the size of the value to fit in 16
bits by discarding the uppermost bits as needed.
þ Addr(operand) returns the effective address of the operand (the result
of the effective address calculation prior to adding the segment base).
þ ZeroExtend(value) returns a value zero-extended to the operand-size
attribute of the instruction. For example, if OperandSize = 32,
ZeroExtend of a byte value of -10 converts the byte from F6H to
doubleword with hexadecimal value 000000F6H. If the value passed to
ZeroExtend and the operand-size attribute are the same size,
ZeroExtend returns the value unaltered.
þ SignExtend(value) returns a value sign-extended to the operand-size
attribute of the instruction. For example, if OperandSize = 32,
SignExtend of a byte containing the value -10 converts the byte from
F6H to a doubleword with hexadecimal value FFFFFFF6H. If the value
passed to SignExtend and the operand-size attribute are the same size,
SignExtend returns the value unaltered.
þ Push(value) pushes a value onto the stack. The number of bytes pushed
is determined by the operand-size attribute of the instruction. The
action of Push is as follows:
IF StackAddrSize = 16
THEN
IF OperandSize = 16
THEN
SP  SP - 2;
SS:[SP]  value; (* 2 bytes assigned starting at
byte address in SP *)
ELSE (* OperandSize = 32 *)
SP  SP - 4;
SS:[SP]  value; (* 4 bytes assigned starting at
byte address in SP *)
FI;
ELSE (* StackAddrSize = 32 *)
IF OperandSize = 16
THEN
ESP  ESP - 2;
SS:[ESP]  value; (* 2 bytes assigned starting at
byte address in ESP*)
ELSE (* OperandSize = 32 *)
ESP  ESP - 4;
SS:[ESP]  value; (* 4 bytes assigned starting at
byte address in ESP*)
FI;
FI;
þ Pop(value) removes the value from the top of the stack and returns it.
The statement EAX  Pop( ); assigns to EAX the 32-bit value that Pop
took from the top of the stack. Pop will return either a word or a
doubleword depending on the operand-size attribute. The action of Pop
is as follows:
IF StackAddrSize = 16
THEN
IF OperandSize = 16
THEN
ret val  SS:[SP]; (* 2-byte value *)
SP  SP + 2;
ELSE (* OperandSize = 32 *)
ret val  SS:[SP]; (* 4-byte value *)
SP  SP + 4;
FI;
ELSE (* StackAddrSize = 32 *)
IF OperandSize = 16
THEN
ret val  SS:[ESP]; (* 2 bytes value *)
ESP  ESP + 2;
ELSE (* OperandSize = 32 *)
ret val  SS:[ESP]; (* 4 bytes value *)
ESP  ESP + 4;
FI;
FI;
RETURN(ret val); (*returns a word or doubleword*)
þ Bit[BitBase, BitOffset] returns the address of a bit within a bit
string, which is a sequence of bits in memory or a register. Bits are
numbered from low-order to high-order within registers and within
memory bytes. In memory, the two bytes of a word are stored with the
low-order byte at the lower address.
If the base operand is a register, the offset can be in the range 0..31.
This offset addresses a bit within the indicated register. An example,
"BIT[EAX, 21]," is illustrated in Figure 17-3.
If BitBase is a memory address, BitOffset can range from -2 gigabits to 2
gigabits. The addressed bit is numbered (Offset MOD 8) within the byte at
address (BitBase + (BitOffset DIV 8)), where DIV is signed division with
rounding towards negative infinity, and MOD returns a positive number.
This is illustrated in Figure 17-4.
þ I-O-Permission(I-O-Address, width) returns TRUE or FALSE depending on
the I/O permission bitmap and other factors. This function is defined as
follows:
IF TSS type is 286 THEN RETURN FALSE; FI;
Ptr  [TSS + 66]; (* fetch bitmap pointer *)
BitStringAddr  SHR (I-O-Address, 3) + Ptr;
MaskShift  I-O-Address AND 7;
CASE width OF:
BYTE: nBitMask  1;
WORD: nBitMask  3;
DWORD: nBitMask  15;
ESAC;
mask  SHL (nBitMask, MaskShift);
CheckString  [BitStringAddr] AND mask;
IF CheckString = 0
THEN RETURN (TRUE);
ELSE RETURN (FALSE);
FI;
þ Switch-Tasks is the task switching function described in Chapter 7.
17.2.2.6 Description
The "Description" section contains further explanation of the instruction's
operation.
Figure 17-3. Bit Offset for BIT[EAX, 21]
31 21 0
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º º º º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
 
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄBITOFFSET = 21ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Figure 17-4. Memory Bit Indexing
BIT INDEXING (POSITIVE OFFSET)
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
ÉÍÍÍÍÑÍÑÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
º ³ ³ ³ ³ º
ÈÍÍÍÍÏÍÏÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
³ BITBASE + 1 ³ BITBASE ³ BITBASE - 1 ³
 ³
ÀÄÄÄÄÄÄÄÄOFFSET = 13ÄÄÄÄÄÄÄÙ
BIT INDEXING (NEGATIVE OFFSET)
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÑÍÑÍÍÍÍÍÍÍÍÍÍ»
º ³ ³ ³ ³ º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÏÍÏÍÍÍÍÍÍÍÍÍͼ
³ BITBASE ³ BITBASE - 1 ³ BITBASE - 2 ³
³ 
ÀÄÄÄÄÄOFFSET = -11ÄÄÄÙ
17.2.2.7 Flags Affected
The "Flags Affected" section lists the flags that are affected by the
instruction, as follows:
þ If a flag is always cleared or always set by the instruction, the
value is given (0 or 1) after the flag name. Arithmetic and logical
instructions usually assign values to the status flags in the uniform
manner described in Appendix C. Nonconventional assignments are
described in the "Operation" section.
þ The values of flags listed as "undefined" may be changed by the
instruction in an indeterminate manner.
All flags not listed are unchanged by the instruction.
17.2.2.8 Protected Mode Exceptions
This section lists the exceptions that can occur when the instruction is
executed in 80386 Protected Mode. The exception names are a pound sign (#)
followed by two letters and an optional error code in parentheses. For
example, #GP(0) denotes a general protection exception with an error code of
0. Table 17-6 associates each two-letter name with the corresponding
interrupt number.
Chapter 9 describes the exceptions and the 80386 state upon entry to the
exception.
Application programmers should consult the documentation provided with
their operating systems to determine the actions taken when exceptions
occur.
Table 17-6. 80386 Exceptions
Mnemonic Interrupt Description
#UD 6 Invalid opcode
#NM 7 Coprocessor not available
#DF 8 Double fault
#TS 10 Invalid TSS
#NP 11 Segment or gate not present
#SS 12 Stack fault
#GP 13 General protection fault
#PF 14 Page fault
#MF 16 Math (coprocessor) fault
17.2.2.9 Real Address Mode Exceptions
Because less error checking is performed by the 80386 in Real Address Mode,
this mode has fewer exception conditions. Refer to Chapter 14 for further
information on these exceptions.
17.2.2.10 Virtual-8086 Mode Exceptions
Virtual 8086 tasks provide the ability to simulate Virtual 8086 machines.
Virtual 8086 Mode exceptions are similar to those for the 8086 processor,
but there are some differences. Refer to Chapter 15 for details.
AAA ÄÄ ASCII Adjust after Addition
Opcode Instruction Clocks Description
37 AAA 4 ASCII adjust AL after addition
Operation
IF ((AL AND 0FH) > 9) OR (AF = 1)
THEN
AL  (AL + 6) AND 0FH;
AH  AH + 1;
AF  1;
CF  1;
ELSE
CF  0;
AF  0;
FI;
Description
Execute AAA only following an ADD instruction that leaves a byte result
in the AL register. The lower nibbles of the operands of the ADD instruction
should be in the range 0 through 9 (BCD digits). In this case, AAA adjusts
AL to contain the correct decimal digit result. If the addition produced a
decimal carry, the AH register is incremented, and the carry and auxiliary
carry flags are set to 1. If there was no decimal carry, the carry and
auxiliary flags are set to 0 and AH is unchanged. In either case, AL is left
with its top nibble set to 0. To convert AL to an ASCII result, follow the
AAA instruction with OR AL, 30H.
Flags Affected
AF and CF as described above; OF, SF, ZF, and PF are undefined
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
AAD ÄÄ ASCII Adjust AX before Division
Opcode Instruction Clocks Description
D5 0A AAD 19 ASCII adjust AX before division
Operation
AL  AH * 10 + AL;
AH  0;
Description
AAD is used to prepare two unpacked BCD digits (the least-significant
digit in AL, the most-significant digit in AH) for a division operation that
will yield an unpacked result. This is accomplished by setting AL to
AL + (10 * AH), and then setting AH to 0. AX is then equal to the binary
equivalent of the original unpacked two-digit number.
Flags Affected
SF, ZF, and PF as described in Appendix C; OF, AF, and CF are undefined
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
AAM ÄÄ ASCII Adjust AX after Multiply
Opcode Instruction Clocks Description
D4 0A AAM 17 ASCII adjust AX after multiply
Operation
AH  AL / 10;
AL  AL MOD 10;
Description
Execute AAM only after executing a MUL instruction between two unpacked
BCD digits that leaves the result in the AX register. Because the result is
less than 100, it is contained entirely in the AL register. AAM unpacks the
AL result by dividing AL by 10, leaving the quotient (most-significant
digit) in AH and the remainder (least-significant digit) in AL.
Flags Affected
SF, ZF, and PF as described in Appendix C; OF, AF, and CF are undefined
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
AAS ÄÄ ASCII Adjust AL after Subtraction
Opcode Instruction Clocks Description
3F AAS 4 ASCII adjust AL after subtraction
Operation
IF (AL AND 0FH) > 9 OR AF = 1
THEN
AL  AL - 6;
AL  AL AND 0FH;
AH  AH - 1;
AF  1;
CF  1;
ELSE
CF  0;
AF  0;
FI;
Description
Execute AAS only after a SUB instruction that leaves the byte result in the
AL register. The lower nibbles of the operands of the SUB instruction must
have been in the range 0 through 9 (BCD digits). In this case, AAS adjusts
AL so it contains the correct decimal digit result. If the subtraction
produced a decimal carry, the AH register is decremented, and the carry and
auxiliary carry flags are set to 1. If no decimal carry occurred, the carry
and auxiliary carry flags are set to 0, and AH is unchanged. In either case,
AL is left with its top nibble set to 0. To convert AL to an ASCII result,
follow the AAS with OR AL, 30H.
Flags Affected
AF and CF as described above; OF, SF, ZF, and PF are undefined
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
ADC ÄÄ Add with Carry
Opcode Instruction Clocks Description
14 ib ADC AL,imm8 2 Add with carry immediate byte to AL
15 iw ADC AX,imm16 2 Add with carry immediate word to AX
15 id ADC EAX,imm32 2 Add with carry immediate dword to EAX
80 /2 ib ADC r/m8,imm8 2/7 Add with carry immediate byte to r/m
byte
81 /2 iw ADC r/m16,imm16 2/7 Add with carry immediate word to r/m
word
81 /2 id ADC r/m32,imm32 2/7 Add with CF immediate dword to r/m
dword
83 /2 ib ADC r/m16,imm8 2/7 Add with CF sign-extended immediate
byte to r/m word
83 /2 ib ADC r/m32,imm8 2/7 Add with CF sign-extended immediate
byte into r/m dword
10 /r ADC r/m8,r8 2/7 Add with carry byte register to r/m
byte
11 /r ADC r/m16,r16 2/7 Add with carry word register to r/m
word
11 /r ADC r/m32,r32 2/7 Add with CF dword register to r/m dword
12 /r ADC r8,r/m8 2/6 Add with carry r/m byte to byte
register
13 /r ADC r16,r/m16 2/6 Add with carry r/m word to word
register
13 /r ADC r32,r/m32 2/6 Add with CF r/m dword to dword register
Operation
DEST  DEST + SRC + CF;
Description
ADC performs an integer addition of the two operands DEST and SRC and the
carry flag, CF. The result of the addition is assigned to the first operand
(DEST), and the flags are set accordingly. ADC is usually executed as part
of a multi-byte or multi-word addition operation. When an immediate byte
value is added to a word or doubleword operand, the immediate value is first
sign-extended to the size of the word or doubleword operand.
Flags Affected
OF, SF, ZF, AF, CF, and PF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) if page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
ADD ÄÄ Add
Opcode Instruction Clocks Description
04 ib ADD AL,imm8 2 Add immediate byte to AL
05 iw ADD AX,imm16 2 Add immediate word to AX
05 id ADD EAX,imm32 2 Add immediate dword to EAX
80 /0 ib ADD r/m8,imm8 2/7 Add immediate byte to r/m byte
81 /0 iw ADD r/m16,imm16 2/7 Add immediate word to r/m word
81 /0 id ADD r/m32,imm32 2/7 Add immediate dword to r/m dword
83 /0 ib ADD r/m16,imm8 2/7 Add sign-extended immediate byte
to r/m word
83 /0 ib ADD r/m32,imm8 2/7 Add sign-extended immediate byte
to r/m dword
00 /r ADD r/m8,r8 2/7 Add byte register to r/m byte
01 /r ADD r/m16,r16 2/7 Add word register to r/m word
01 /r ADD r/m32,r32 2/7 Add dword register to r/m dword
02 /r ADD r8,r/m8 2/6 Add r/m byte to byte register
03 /r ADD r16,r/m16 2/6 Add r/m word to word register
03 /r ADD r32,r/m32 2/6 Add r/m dword to dword register
Operation
DEST  DEST + SRC;
Description
ADD performs an integer addition of the two operands (DEST and SRC). The
result of the addition is assigned to the first operand (DEST), and the
flags are set accordingly.
When an immediate byte is added to a word or doubleword operand, the
immediate value is sign-extended to the size of the word or doubleword
operand.
Flags Affected
OF, SF, ZF, AF, CF, and PF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
AND ÄÄ Logical AND
Opcode Instruction Clocks Description
24 ib AND AL,imm8 2 AND immediate byte to AL
25 iw AND AX,imm16 2 AND immediate word to AX
25 id AND EAX,imm32 2 AND immediate dword to EAX
80 /4 ib AND r/m8,imm8 2/7 AND immediate byte to r/m byte
81 /4 iw AND r/m16,imm16 2/7 AND immediate word to r/m word
81 /4 id AND r/m32,imm32 2/7 AND immediate dword to r/m dword
83 /4 ib AND r/m16,imm8 2/7 AND sign-extended immediate byte
with r/m word
83 /4 ib AND r/m32,imm8 2/7 AND sign-extended immediate byte
with r/m dword
20 /r AND r/m8,r8 2/7 AND byte register to r/m byte
21 /r AND r/m16,r16 2/7 AND word register to r/m word
21 /r AND r/m32,r32 2/7 AND dword register to r/m dword
22 /r AND r8,r/m8 2/6 AND r/m byte to byte register
23 /r AND r16,r/m16 2/6 AND r/m word to word register
23 /r AND r32,r/m32 2/6 AND r/m dword to dword register
Operation
DEST  DEST AND SRC;
CF  0;
OF  0;
Description
Each bit of the result of the AND instruction is a 1 if both corresponding
bits of the operands are 1; otherwise, it becomes a 0.
Flags Affected
CF = 0, OF = 0; PF, SF, and ZF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
ARPL ÄÄ Adjust RPL Field of Selector
Opcode Instruction Clocks Description
63 /r ARPL r/m16,r16 pm=20/21 Adjust RPL of r/m16 to not
less than RPL of r16
Operation
IF RPL bits(0,1) of DEST < RPL bits(0,1) of SRC
THEN
ZF  1;
RPL bits(0,1) of DEST  RPL bits(0,1) of SRC;
ELSE
ZF  0;
FI;
Description
The ARPL instruction has two operands. The first operand is a 16-bit
memory variable or word register that contains the value of a selector. The
second operand is a word register. If the RPL field ("requested privilege
level"ÄÄbottom two bits) of the first operand is less than the RPL field of
the second operand, the zero flag is set to 1 and the RPL field of the
first operand is increased to match the second operand. Otherwise, the zero
flag is set to 0 and no change is made to the first operand.
ARPL appears in operating system software, not in application programs. It
is used to guarantee that a selector parameter to a subroutine does not
request more privilege than the caller is allowed. The second operand of
ARPL is normally a register that contains the CS selector value of the
caller.
Flags Affected
ZF as described above
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 6; ARPL is not recognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
BOUND ÄÄ Check Array Index Against Bounds
Opcode Instruction Clocks Description
62 /r BOUND r16,m16&16 10 Check if r16 is within bounds
(passes test)
62 /r BOUND r32,m32&32 10 Check if r32 is within bounds
(passes test)
Operation
IF (LeftSRC < [RightSRC] OR LeftSRC > [RightSRC + OperandSize/8])
(* Under lower bound or over upper bound *)
THEN Interrupt 5;
FI;
Description
BOUND ensures that a signed array index is within the limits specified by a
block of memory consisting of an upper and a lower bound. Each bound uses
one word for an operand-size attribute of 16 bits and a doubleword for an
operand-size attribute of 32 bits. The first operand (a register) must be
greater than or equal to the first bound in memory (lower bound), and less
than or equal to the second bound in memory (upper bound). If the register
is not within bounds, an Interrupt 5 occurs; the return EIP points to the
BOUND instruction.
The bounds limit data structure is usually placed just before the array
itself, making the limits addressable via a constant offset from the
beginning of the array.
Flags Affected
None
Protected Mode Exceptions
Interrupt 5 if the bounds test fails, as described above; #GP(0) for an
illegal memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
The second operand must be a memory operand, not a register. If BOUND is
executed with a ModRM byte representing a register as the second operand,
#UD occurs.
Real Address Mode Exceptions
Interrupt 5 if the bounds test fails; Interrupt 13 if any part of the
operand would lie outside of the effective address space from 0 to 0FFFFH;
Interrupt 6 if the second operand is a register
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
BSF ÄÄ Bit Scan Forward
Opcode Instruction Clocks Description
0F BC BSF r16,r/m16 10+3n Bit scan forward on r/m word
0F BC BSF r32,r/m32 10+3n Bit scan forward on r/m dword
Notes
is the number of leading zero bits.
Operation
IF r/m = 0
THEN
ZF  1;
register  UNDEFINED;
ELSE
temp  0;
ZF  0;
WHILE BIT[r/m, temp = 0]
DO
temp  temp + 1;
register  temp;
OD;
FI;
Description
BSF scans the bits in the second word or doubleword operand starting with
bit 0. The ZF flag is cleared if the bits are all 0; otherwise, the ZF flag
is set and the destination register is loaded with the bit index of the
first set bit.
Flags Affected
ZF as described above
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS, ES,
FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
BSR ÄÄ Bit Scan Reverse
Opcode Instruction Clocks Description
0F BD BSR r16,r/m16 10+3n Bit scan reverse on r/m word
0F BD BSR r32,r/m32 10+3n Bit scan reverse on r/m dword
Operation
IF r/m = 0
THEN
ZF  1;
register  UNDEFINED;
ELSE
temp  OperandSize - 1;
ZF  0;
WHILE BIT[r/m, temp] = 0
DO
temp  temp - 1;
register  temp;
OD;
FI;
Description
BSR scans the bits in the second word or doubleword operand from the most
significant bit to the least significant bit. The ZF flag is cleared if the
bits are all 0; otherwise, ZF is set and the destination register is loaded
with the bit index of the first set bit found when scanning in the reverse
direction.
Flags Affected
ZF as described above
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
BT ÄÄ Bit Test
Opcode Instruction Clocks Description
0F A3 BT r/m16,r16 3/12 Save bit in carry flag
0F A3 BT r/m32,r32 3/12 Save bit in carry flag
0F BA /4 ib BT r/m16,imm8 3/6 Save bit in carry flag
0F BA /4 ib BT r/m32,imm8 3/6 Save bit in carry flag
Operation
CF  BIT[LeftSRC, RightSRC];
Description
BT saves the value of the bit indicated by the base (first operand) and the
bit offset (second operand) into the carry flag.
Flags Affected
CF as described above
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS, ES,
FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
Notes
The index of the selected bit can be given by the immediate constant in the
instruction or by a value in a general register. Only an 8-bit immediate
value is used in the instruction. This operand is taken modulo 32, so the
range of immediate bit offsets is 0..31. This allows any bit within a
register to be selected. For memory bit strings, this immediate field gives
only the bit offset within a word or doubleword. Immediate bit offsets
larger than 31 are supported by using the immediate bit offset field in
combination with the displacement field of the memory operand. The low-order
3 to 5 bits of the immediate bit offset are stored in the immediate bit
offset field, and the high-order 27 to 29 bits are shifted and combined with
the byte displacement in the addressing mode.
When accessing a bit in memory, the 80386 may access four bytes starting
from the memory address given by:
Effective Address + (4 * (BitOffset DIV 32))
for a 32-bit operand size, or two bytes starting from the memory address
given by:
Effective Address + (2 * (BitOffset DIV 16))
for a 16-bit operand size. It may do so even when only a single byte needs
to be accessed in order to reach the given bit. You must therefore avoid
referencing areas of memory close to address space holes. In particular,
avoid references to memory-mapped I/O registers. Instead, use the MOV
instructions to load from or store to these addresses, and use the register
form of these instructions to manipulate the data.
BTC ÄÄ Bit Test and Complement
Opcode Instruction Clocks Description
0F BB BTC r/m16,r16 6/13 Save bit in carry flag and complement
0F BB BTC r/m32,r32 6/13 Save bit in carry flag and complement
0F BA /7 ib BTC r/m16,imm8 6/8 Save bit in carry flag and complement
0F BA /7 ib BTC r/m32,imm8 6/8 Save bit in carry flag and complement
Operation
CF  BIT[LeftSRC, RightSRC];
BIT[LeftSRC, RightSRC]  NOT BIT[LeftSRC, RightSRC];
Description
BTC saves the value of the bit indicated by the base (first operand) and the
bit offset (second operand) into the carry flag and then complements the
bit.
Flags Affected
CF as described above
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
Notes
The index of the selected bit can be given by the immediate constant in the
instruction or by a value in a general register. Only an 8-bit immediate
value is used in the instruction. This operand is taken modulo 32, so the
range of immediate bit offsets is 0..31. This allows any bit within a
register to be selected. For memory bit strings, this immediate field gives
only the bit offset within a word or doubleword. Immediate bit offsets
larger than 31 are supported by using the immediate bit offset field in
combination with the displacement field of the memory operand. The low-order
3 to 5 bits of the immediate bit offset are stored in the immediate bit
offset field, and the high-order 27 to 29 bits are shifted and combined with
the byte displacement in the addressing mode.
When accessing a bit in memory, the 80386 may access four bytes starting
from the memory address given by:
Effective Address + (4 * (BitOffset DIV 32))
for a 32-bit operand size, or two bytes starting from the memory address
given by:
Effective Address + (2 * (BitOffset DIV 16))
for a 16-bit operand size. It may do so even when only a single byte needs
to be accessed in order to reach the given bit. You must therefore avoid
referencing areas of memory close to address space holes. In particular,
avoid references to memory-mapped I/O registers. Instead, use the MOV
instructions to load from or store to these addresses, and use the register
form of these instructions to manipulate the data.
BTR ÄÄ Bit Test and Reset
Opcode Instruction Clocks Description
0F B3 BTR r/m16,r16 6/13 Save bit in carry flag and reset
0F B3 BTR r/m32,r32 6/13 Save bit in carry flag and reset
0F BA /6 ib BTR r/m16,imm8 6/8 Save bit in carry flag and reset
0F BA /6 ib BTR r/m32,imm8 6/8 Save bit in carry flag and reset
Operation
CF  BIT[LeftSRC, RightSRC];
BIT[LeftSRC, RightSRC]  0;
Description
BTR saves the value of the bit indicated by the base (first operand) and the
bit offset (second operand) into the carry flag and then stores 0 in the
bit.
Flags Affected
CF as described above
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
Notes
The index of the selected bit can be given by the immediate constant in the
instruction or by a value in a general register. Only an 8-bit immediate
value is used in the instruction. This operand is taken modulo 32, so the
range of immediate bit offsets is 0..31. This allows any bit within a
register to be selected. For memory bit strings, this immediate field gives
only the bit offset within a word or doubleword. Immediate bit offsets
larger than 31 (or 15) are supported by using the immediate bit offset field
in combination with the displacement field of the memory operand. The
low-order 3 to 5 bits of the immediate bit offset are stored in the
immediate bit offset field, and the high-order 27 to 29 bits are shifted and
combined with the byte displacement in the addressing mode.
When accessing a bit in memory, the 80386 may access four bytes starting
from the memory address given by:
Effective Address + 4 * (BitOffset DIV 32)
for a 32-bit operand size, or two bytes starting from the memory address
given by:
Effective Address + 2 * (BitOffset DIV 16)
for a 16-bit operand size. It may do so even when only a single byte needs
to be accessed in order to reach the given bit. You must therefore avoid
referencing areas of memory close to address space holes. In particular,
avoid references to memory-mapped I/O registers. Instead, use the MOV
instructions to load from or store to these addresses, and use the register
form of these instructions to manipulate the data.
BTS ÄÄ Bit Test and Set
Opcode Instruction Clocks Description
0F AB BTS r/m16,r16 6/13 Save bit in carry flag and set
0F AB BTS r/m32,r32 6/13 Save bit in carry flag and set
0F BA /5 ib BTS r/m16,imm8 6/8 Save bit in carry flag and set
0F BA /5 ib BTS r/m32,imm8 6/8 Save bit in carry flag and set
Operation
CF  BIT[LeftSRC, RightSRC];
BIT[LeftSRC, RightSRC]  1;
Description
BTS saves the value of the bit indicated by the base (first operand) and the
bit offset (second operand) into the carry flag and then stores 1 in the
bit.
Flags Affected
CF as described above
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
Notes
The index of the selected bit can be given by the immediate constant in the
instruction or by a value in a general register. Only an 8-bit immediate
value is used in the instruction. This operand is taken modulo 32, so the
range of immediate bit offsets is 0..31. This allows any bit within a
register to be selected. For memory bit strings, this immediate field gives
only the bit offset within a word or doubleword. Immediate bit offsets
larger than 31 are supported by using the immediate bit offset field in
combination with the displacement field of the memory operand. The
low-order 3 to 5 bits of the immediate bit offset are stored in the
immediate bit offset field, and the high order 27 to 29 bits are shifted and
combined with the byte displacement in the addressing mode.
When accessing a bit in memory, the processor may access four bytes starting
from the memory address given by:
Effective Address + (4 * (BitOffset DIV 32))
for a 32-bit operand size, or two bytes starting from the memory address
given by:
Effective Address + (2 * (BitOffset DIV 16))
for a 16-bit operand size. It may do this even when only a single byte needs
to be accessed in order to get at the given bit. Thus the programmer must be
careful to avoid referencing areas of memory close to address space holes.
In particular, avoid references to memory-mapped I/O registers. Instead, use
the MOV instructions to load from or store to these addresses, and use the
register form of these instructions to manipulate the data.
CALL ÄÄ Call Procedure
Opcode Instruction Clocks
Values of ts are given by the following table:
New Task
386 TSS 386 TSS 286 TSS
Old VM = 0 VM = 1
Task Via Task Gate?
N Y N Y N Y
386 300 309 217 226 273 282
TSS VM=0
286 298 307 217 226 273 282
TSS Description
E8 cw CALL rel16 7+m Call near, displacement relative
to next instruction
FF /2 CALL r/m16 7+m/10+m Call near, register
indirect/memory indirect
9A cd CALL ptr16:16 17+m,pm=34+m Call intersegment, to full
pointer given
9A cd CALL ptr16:16 pm=52+m Call gate, same privilege
9A cd CALL ptr16:16 pm=86+m Call gate, more privilege, no
parameters
9A cd CALL ptr16:16 pm=94+4x+m Call gate, more privilege, x
parameters
9A cd CALL ptr16:16 ts Call to task
FF /3 CALL m16:16 22+m,pm=38+m Call intersegment, address at
r/m dword
FF /3 CALL m16:16 pm=56+m Call gate, same privilege
FF /3 CALL m16:16 pm=90+m Call gate, more privilege, no
parameters
FF /3 CALL m16:16 pm=98+4x+m Call gate, more privilege, x
parameters
FF /3 CALL m16:16 5 + ts Call to task
E8 cd CALL rel32 7+m Call near, displacement relative
to next instruction
FF /2 CALL r/m32 7+m/10+m Call near, indirect
9A cp CALL ptr16:32 17+m,pm=34+m Call intersegment, to full
pointer given
9A cp CALL ptr16:32 pm=52+m Call gate, same privilege
9A cp CALL ptr16:32 pm=86+m Call gate, more privilege, no
parameters
9A cp CALL ptr32:32 pm=94+4x+m Call gate, more privilege, x
parameters
9A cp CALL ptr16:32 ts Call to task
FF /3 CALL m16:32 22+m,pm=38+m Call intersegment, address at
r/m dword
FF /3 CALL m16:32 pm=56+m Call gate, same privilege
FF /3 CALL m16:32 pm=90+m Call gate, more privilege, no
parameters
FF /3 CALL m16:32 pm=98+4x+m Call gate, more privilege, x
parameters
FF /3 CALL m16:32 5 + ts Call to task
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTE:
Values of ts are given by the following table:
New Task
386 TSS 386 TSS 286 TSS
Old VM = 0 VM = 1
Task Via Task Gate?
N Y N Y N Y
386 300 309 217 226 273 282
TSS VM=0
286 298 307 217 226 273 282
TSS
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
IF rel16 or rel32 type of call
THEN (* near relative call *)
IF OperandSize = 16
THEN
Push(IP);
EIP  (EIP + rel16) AND 0000FFFFH;
ELSE (* OperandSize = 32 *)
Push(EIP);
EIP  EIP + rel32;
FI;
FI;
IF r/m16 or r/m32 type of call
THEN (* near absolute call *)
IF OperandSize = 16
THEN
Push(IP);
EIP  [r/m16] AND 0000FFFFH;
ELSE (* OperandSize = 32 *)
Push(EIP);
EIP  [r/m32];
FI;
FI;
IF (PE = 0 OR (PE = 1 AND VM = 1))
(* real mode or virtual 8086 mode *)
AND instruction = far CALL
(* i.e., operand type is m16:16, m16:32, ptr16:16, ptr16:32 *)
THEN
IF OperandSize = 16
THEN
Push(CS);
Push(IP); (* address of next instruction; 16 bits *)
ELSE
Push(CS); (* padded with 16 high-order bits *)
Push(EIP); (* address of next instruction; 32 bits *)
FI;
IF operand type is m16:16 or m16:32
THEN (* indirect far call *)
IF OperandSize = 16
THEN
CS:IP  [m16:16];
EIP  EIP AND 0000FFFFH; (* clear upper 16 bits *)
ELSE (* OperandSize = 32 *)
CS:EIP  [m16:32];
FI;
FI;
IF operand type is ptr16:16 or ptr16:32
THEN (* direct far call *)
IF OperandSize = 16
THEN
CS:IP  ptr16:16;
EIP  EIP AND 0000FFFFH; (* clear upper 16 bits *)
ELSE (* OperandSize = 32 *)
CS:EIP  ptr16:32;
FI;
FI;
FI;
IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)
AND instruction = far CALL
THEN
If indirect, then check access of EA doubleword;
#GP(0) if limit violation;
New CS selector must not be null else #GP(0);
Check that new CS selector index is within its
descriptor table limits; else #GP(new CS selector);
Examine AR byte of selected descriptor for various legal values;
depending on value:
go to CONFORMING-CODE-SEGMENT;
go to NONCONFORMING-CODE-SEGMENT;
go to CALL-GATE;
go to TASK-GATE;
go to TASK-STATE-SEGMENT;
ELSE #GP(code segment selector);
FI;
CONFORMING-CODE-SEGMENT:
DPL must be ó CPL ELSE #GP(code segment selector);
Segment must be present ELSE #NP(code segment selector);
Stack must be big enough for return address ELSE #SS(0);
Instruction pointer must be in code segment limit ELSE #GP(0);
Load code segment descriptor into CS register;
Load CS with new code segment selector;
Load EIP with zero-extend(new offset);
IF OperandSize=16 THEN EIP  EIP AND 0000FFFFH; FI;
NONCONFORMING-CODE-SEGMENT:
RPL must be ó CPL ELSE #GP(code segment selector)
DPL must be = CPL ELSE #GP(code segment selector)
Segment must be present ELSE #NP(code segment selector)
Stack must be big enough for return address ELSE #SS(0)
Instruction pointer must be in code segment limit ELSE #GP(0)
Load code segment descriptor into CS register
Load CS with new code segment selector
Set RPL of CS to CPL
Load EIP with zero-extend(new offset);
IF OperandSize=16 THEN EIP  EIP AND 0000FFFFH; FI;
CALL-GATE:
Call gate DPL must be ò CPL ELSE #GP(call gate selector)
Call gate DPL must be ò RPL ELSE #GP(call gate selector)
Call gate must be present ELSE #NP(call gate selector)
Examine code segment selector in call gate descriptor:
Selector must not be null ELSE #GP(0)
Selector must be within its descriptor table
limits ELSE #GP(code segment selector)
AR byte of selected descriptor must indicate code
segment ELSE #GP(code segment selector)
DPL of selected descriptor must be ó CPL ELSE
#GP(code segment selector)
IF non-conforming code segment AND DPL < CPL
THEN go to MORE-PRIVILEGE
ELSE go to SAME-PRIVILEGE
FI;
MORE-PRIVILEGE:
Get new SS selector for new privilege level from TSS
Check selector and descriptor for new SS:
Selector must not be null ELSE #TS(0)
Selector index must be within its descriptor
table limits ELSE #TS(SS selector)
Selector's RPL must equal DPL of code segment
ELSE #TS(SS selector)
Stack segment DPL must equal DPL of code
segment ELSE #TS(SS selector)
Descriptor must indicate writable data segment
ELSE #TS(SS selector)
Segment present ELSE #SS(SS selector)
IF OperandSize=32
THEN
New stack must have room for parameters plus 16 bytes
ELSE #SS(0)
EIP must be in code segment limit ELSE #GP(0)
Load new SS:eSP value from TSS
Load new CS:EIP value from gate
ELSE
New stack must have room for parameters plus 8 bytes ELSE #SS(0)
IP must be in code segment limit ELSE #GP(0)
Load new SS:eSP value from TSS
Load new CS:IP value from gate
FI;
Load CS descriptor
Load SS descriptor
Push long pointer of old stack onto new stack
Get word count from call gate, mask to 5 bits
Copy parameters from old stack onto new stack
Push return address onto new stack
Set CPL to stack segment DPL
Set RPL of CS to CPL
SAME-PRIVILEGE:
IF OperandSize=32
THEN
Stack must have room for 6-byte return address (padded to 8 bytes)
ELSE #SS(0)
EIP must be within code segment limit ELSE #GP(0)
Load CS:EIP from gate
ELSE
Stack must have room for 4-byte return address ELSE #SS(0)
IP must be within code segment limit ELSE #GP(0)
Load CS:IP from gate
FI;
Push return address onto stack
Load code segment descriptor into CS register
Set RPL of CS to CPL
TASK-GATE:
Task gate DPL must be ò CPL ELSE #TS(gate selector)
Task gate DPL must be ò RPL ELSE #TS(gate selector)
Task Gate must be present ELSE #NP(gate selector)
Examine selector to TSS, given in Task Gate descriptor:
Must specify global in the local/global bit ELSE #TS(TSS selector)
Index must be within GDT limits ELSE #TS(TSS selector)
TSS descriptor AR byte must specify nonbusy TSS
ELSE #TS(TSS selector)
Task State Segment must be present ELSE #NP(TSS selector)
SWITCH-TASKS (with nesting) to TSS
IP must be in code segment limit ELSE #TS(0)
TASK-STATE-SEGMENT:
TSS DPL must be ò CPL else #TS(TSS selector)
TSS DPL must be ò RPL ELSE #TS(TSS selector)
TSS descriptor AR byte must specify available TSS
ELSE #TS(TSS selector)
Task State Segment must be present ELSE #NP(TSS selector)
SWITCH-TASKS (with nesting) to TSS
IP must be in code segment limit ELSE #TS(0)
Description
The CALL instruction causes the procedure named in the operand to be
executed. When the procedure is complete (a return instruction is executed
within the procedure), execution continues at the instruction that follows
the CALL instruction.
The action of the different forms of the instruction are described below.
Near calls are those with destinations of type r/m16, r/m32, rel16, rel32;
changing or saving the segment register value is not necessary. The CALL
rel16 and CALL rel32 forms add a signed offset to the address of the
instruction following CALL to determine the destination. The rel16 form is
used when the instruction's operand-size attribute is 16 bits; rel32 is used
when the operand-size attribute is 32 bits. The result is stored in the
32-bit EIP register. With rel16, the upper 16 bits of EIP are cleared,
resulting in an offset whose value does not exceed 16 bits. CALL r/m16 and
CALL r/m32 specify a register or memory location from which the absolute
segment offset is fetched. The offset fetched from r/m is 32 bits for an
operand-size attribute of 32 (r/m32), or 16 bits for an operand-size of 16
(r/m16). The offset of the instruction following CALL is pushed onto the
stack. It will be popped by a near RET instruction within the procedure. The
CS register is not changed by this form of CALL.
The far calls, CALL ptr16:16 and CALL ptr16:32, use a four-byte or six-byte
operand as a long pointer to the procedure called. The CALL m16:16 and
m16:32 forms fetch the long pointer from the memory location
specified (indirection). In Real Address Mode or Virtual 8086 Mode, the long
pointer provides 16 bits for the CS register and 16 or 32 bits for the EIP
register (depending on the operand-size attribute). These forms of the
instruction push both CS and IP or EIP as a return address.
In Protected Mode, both long pointer forms consult the AR byte in the
descriptor indexed by the selector part of the long pointer. Depending on
the value of the AR byte, the call will perform one of the following types
of control transfers:
þ A far call to the same protection level
þ An inter-protection level far call
þ A task switch
For more information on Protected Mode control transfers, refer to
Chapter 6 and Chapter 7.
Flags Affected
All flags are affected if a task switch occurs; no flags are affected if a
task switch does not occur
Protected Mode Exceptions
For far calls: #GP, #NP, #SS, and #TS, as indicated in the list above
For near direct calls: #GP(0) if procedure location is beyond the code
segment limits; #SS(0) if pushing the return address exceeds the bounds of
the stack segment; #PF (fault-code) for a page fault
For a near indirect call: #GP(0) for an illegal memory operand effective
address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address
in the SS segment; #GP(0) if the indirect offset obtained is beyond the code
segment limits; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
Notes
Any far call from a 32-bit code segment to 16-bit code segments should be
made from the first 64K bytes of the 32-bit code segment, since the
operand-size attribute of the instruction is set to 16, thus allowing only a
16-bit return address offset to be saved.
CBW/CWDE ÄÄ Convert Byte to Word/Convert Word to Doubleword
Opcode Instruction Clocks Description
98 CBW 3 AX  sign-extend of AL
98 CWDE 3 EAX  sign-extend of AX
Operation
IF OperandSize = 16 (* instruction = CBW *)
THEN AX  SignExtend(AL);
ELSE (* OperandSize = 32, instruction = CWDE *)
EAX  SignExtend(AX);
FI;
Description
CBW converts the signed byte in AL to a signed word in AX by extending the
most significant bit of AL (the sign bit) into all of the bits of AH. CWDE
converts the signed word in AX to a doubleword in EAX by extending the most
significant bit of AX into the two most significant bytes of EAX. Note that
CWDE is different from CWD. CWD uses DX:AX rather than EAX as a destination.
Flags Affected
None
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
CLC ÄÄ Clear Carry Flag
Opcode Instruction Clocks Description
F8 CLC 2 Clear carry flag
Operation
CF  0;
Description
CLC sets the carry flag to zero. It does not affect other flags or
registers.
Flags Affected
CF = 0
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
CLD ÄÄ Clear Direction Flag
Opcode Instruction Clocks Description
FC CLD 2 Clear direction flag; SI and DI
will increment during string
instructions
Operation
DF  0;
Description
CLD clears the direction flag. No other flags or registers are affected.
After CLD is executed, string operations will increment the index registers
(SI and/or DI) that they use.
Flags Affected
DF = 0
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
CLI ÄÄ Clear Interrupt Flag
Opcode Instruction Clocks Description
FA CLI 3 Clear interrupt flag; interrupts disabled
Operation
IF  0;
Description
CLI clears the interrupt flag if the current privilege level is at least as
privileged as IOPL. No other flags are affected. External interrupts are not
recognized at the end of the CLI instruction or from that point on until the
interrupt flag is set.
Flags Affected
IF = 0
Protected Mode Exceptions
#GP(0) if the current privilege level is greater (has less privilege) than
the IOPL in the flags register. IOPL specifies the least privileged level at
which I/O can be performed.
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
#GP(0) as for Protected Mode
CLTS ÄÄ Clear Task-Switched Flag in CR0
Opcode Instruction Clocks Description
OF 06 CLTS 5 Clear task-switched flag
Operation
TS Flag in CR0  0;
Description
CLTS clears the task-switched (TS) flag in register CR0. This flag is set by
the 80386 every time a task switch occurs. The TS flag is used to manage
processor extensions as follows:
þ Every execution of an ESC instruction is trapped if the TS flag is set.
þ Execution of a WAIT instruction is trapped if the MP flag and the TS
flag are both set.
Thus, if a task switch was made after an ESC instruction was begun, the
processor extension's context may need to be saved before a new ESC
instruction can be issued. The fault handler saves the context and resets
the TS flag.
CLTS appears in operating system software, not in application programs. It
is a privileged instruction that can only be executed at privilege level 0.
Flags Affected
TS = 0 (TS is in CR0, not the flag register)
Protected Mode Exceptions
#GP(0) if CLTS is executed with a current privilege level other than 0
Real Address Mode Exceptions
None (valid in Real Address Mode to allow initialization for Protected
Mode)
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode
CMC ÄÄ Complement Carry Flag
Opcode Instruction Clocks Description
F5 CMC 2 Complement carry flag
Operation
CF  NOT CF;
Description
CMC reverses the setting of the carry flag. No other flags are affected.
Flags Affected
CF as described above
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
CMP ÄÄ Compare Two Operands
Opcode Instruction Clocks Description
3C ib CMP AL,imm8 2 Compare immediate byte to AL
3D iw CMP AX,imm16 2 Compare immediate word to AX
3D id CMP EAX,imm32 2 Compare immediate dword to EAX
80 /7 ib CMP r/m8,imm8 2/5 Compare immediate byte to r/m
byte
81 /7 iw CMP r/m16,imm16 2/5 Compare immediate word to r/m
word
81 /7 id CMP r/m32,imm32 2/5 Compare immediate dword to r/m
dword
83 /7 ib CMP r/m16,imm8 2/5 Compare sign extended immediate
byte to r/m word
83 /7 ib CMP r/m32,imm8 2/5 Compare sign extended immediate
byte to r/m dword
38 /r CMP r/m8,r8 2/5 Compare byte register to r/m
byte
39 /r CMP r/m16,r16 2/5 Compare word register to r/m
word
39 /r CMP r/m32,r32 2/5 Compare dword register to r/m
dword
3A /r CMP r8,r/m8 2/6 Compare r/m byte to byte
register
3B /r CMP r16,r/m16 2/6 Compare r/m word to word
register
3B /r CMP r32,r/m32 2/6 Compare r/m dword to dword
register
Operation
LeftSRC - SignExtend(RightSRC);
(* CMP does not store a result; its purpose is to set the flags *)
Description
CMP subtracts the second operand from the first but, unlike the SUB
instruction, does not store the result; only the flags are changed. CMP is
typically used in conjunction with conditional jumps and the SETcc
instruction. (Refer to Appendix D for the list of signed and unsigned flag
tests provided.) If an operand greater than one byte is compared to an
immediate byte, the byte value is first sign-extended.
Flags Affected
OF, SF, ZF, AF, PF, and CF as described in Appendix C
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS, ES,
FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
CMPS/CMPSB/CMPSW/CMPSD ÄÄ Compare String Operands
Opcode Instruction Clocks Description
A6 CMPS m8,m8 10 Compare bytes ES:[(E)DI] (second
operand) with [(E)SI] (first
operand)
A7 CMPS m16,m16 10 Compare words ES:[(E)DI] (second
operand) with [(E)SI] (first
operand)
A7 CMPS m32,m32 10 Compare dwords ES:[(E)DI]
(second operand) with [(E)SI]
(first operand)
A6 CMPSB 10 Compare bytes ES:[(E)DI] with
DS:[SI]
A7 CMPSW 10 Compare words ES:[(E)DI] with
DS:[SI]
A7 CMPSD 10 Compare dwords ES:[(E)DI] with
DS:[SI]
Operation
IF (instruction = CMPSD) OR
(instruction has operands of type DWORD)
THEN OperandSize  32;
ELSE OperandSize  16;
FI;
IF AddressSize = 16
THEN
use SI for source-index and DI for destination-index
ELSE (* AddressSize = 32 *)
use ESI for source-index and EDI for destination-index;
FI;
IF byte type of instruction
THEN
[source-index] - [destination-index]; (* byte comparison *)
IF DF = 0 THEN IncDec  1 ELSE IncDec  -1; FI;
ELSE
IF OperandSize = 16
THEN
[source-index] - [destination-index]; (* word comparison *)
IF DF = 0 THEN IncDec  2 ELSE IncDec  -2; FI;
ELSE (* OperandSize = 32 *)
[source-index] - [destination-index]; (* dword comparison *)
IF DF = 0 THEN IncDec  4 ELSE IncDec  -4; FI;
FI;
FI;
source-index = source-index + IncDec;
destination-index = destination-index + IncDec;
Description
CMPS compares the byte, word, or doubleword pointed to by the source-index
register with the byte, word, or doubleword pointed to by the
destination-index register.
If the address-size attribute of this instruction is 16 bits, SI and DI
will be used for source- and destination-index registers; otherwise ESI and
EDI will be used. Load the correct index values into SI and DI (or ESI and
EDI) before executing CMPS.
The comparison is done by subtracting the operand indexed by
the destination-index register from the operand indexed by the source-index
register.
Note that the direction of subtraction for CMPS is [SI] - [DI] or
[ESI] - [EDI]. The left operand (SI or ESI) is the source and the right
operand (DI or EDI) is the destination. This is the reverse of the usual
Intel convention in which the left operand is the destination and the right
operand is the source.
The result of the subtraction is not stored; only the flags reflect the
change. The types of the operands determine whether bytes, words, or
doublewords are compared. For the first operand (SI or ESI), the DS register
is used, unless a segment override byte is present. The second operand (DI
or EDI) must be addressable from the ES register; no segment override is
possible.
After the comparison is made, both the source-index register and
destination-index register are automatically advanced. If the direction flag
is 0 (CLD was executed), the registers increment; if the direction flag is 1
(STD was executed), the registers decrement. The registers increment or
decrement by 1 if a byte is compared, by 2 if a word is compared, or by 4 if
a doubleword is compared.
CMPSB, CMPSW and CMPSD are synonyms for the byte, word, and
doubleword CMPS instructions, respectively.
CMPS can be preceded by the REPE or REPNE prefix for block comparison of CX
or ECX bytes, words, or doublewords. Refer to the description of the REP
instruction for more information on this operation.
Flags Affected
OF, SF, ZF, AF, PF, and CF as described in Appendix C
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS, ES,
FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF (fault-code) for a page fault
CWD/CDQ ÄÄ Convert Word to Doubleword/Convert Doubleword to
Quadword
Opcode Instruction Clocks Description
99 CWD 2 DX:AX  sign-extend of AX
99 CDQ 2 EDX:EAX  sign-extend of EAX
Operation
IF OperandSize = 16 (* CWD instruction *)
THEN
IF AX < 0 THEN DX  0FFFFH; ELSE DX  0; FI;
ELSE (* OperandSize = 32, CDQ instruction *)
IF EAX < 0 THEN EDX  0FFFFFFFFH; ELSE EDX  0; FI;
FI;
Description
CWD converts the signed word in AX to a signed doubleword in DX:AX
by extending the most significant bit of AX into all the bits of DX. CDQ
converts the signed doubleword in EAX to a signed 64-bit integer in the
register pair EDX:EAX by extending the most significant bit of EAX
(the sign bit) into all the bits of EDX. Note that CWD is different from
CWDE. CWDE uses EAX as a destination, instead of DX:AX.
Flags Affected
None
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
DAA ÄÄ Decimal Adjust AL after Addition
Opcode Instruction Clocks Description
27 DAA 4 Decimal adjust AL after addition
Operation
IF ((AL AND 0FH) > 9) OR (AF = 1)
THEN
AL  AL + 6;
AF  1;
ELSE
AF  0;
FI;
IF (AL > 9FH) OR (CF = 1)
THEN
AL  AL + 60H;
CF  1;
ELSE CF  0;
FI;
Description
Execute DAA only after executing an ADD instruction that leaves a
two-BCD-digit byte result in the AL register. The ADD operands should
consist of two packed BCD digits. The DAA instruction adjusts AL to
contain the correct two-digit packed decimal result.
Flags Affected
AF and CF as described above; SF, ZF, PF, and CF as described in
Appendix C.
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
DAS ÄÄ Decimal Adjust AL after Subtraction
Opcode Instruction Clocks Description
2F DAS 4 Decimal adjust AL after subtraction
Operation
IF (AL AND 0FH) > 9 OR AF = 1
THEN
AL  AL - 6;
AF  1;
ELSE
AF  0;
FI;
IF (AL > 9FH) OR (CF = 1)
THEN
AL  AL - 60H;
CF  1;
ELSE CF  0;
FI;
Description
Execute DAS only after a subtraction instruction that leaves a
two-BCD-digit byte result in the AL register. The operands should consist
of two packed BCD digits. DAS adjusts AL to contain the correct packed
two-digit decimal result.
Flags Affected
AF and CF as described above; SF, ZF, and PF as described in Appendix C.
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
DEC ÄÄ Decrement by 1
Opcode Instruction Clocks Description
FE /1 DEC r/m8 2/6 Decrement r/m byte by 1
FF /1 DEC r/m16 2/6 Decrement r/m word by 1
DEC r/m32 2/6 Decrement r/m dword by 1
48+rw DEC r16 2 Decrement word register by 1
48+rw DEC r32 2 Decrement dword register by 1
Operation
DEST  DEST - 1;
Description
DEC subtracts 1 from the operand. DEC does not change the carry flag.
To affect the carry flag, use the SUB instruction with an immediate
operand of 1.
Flags Affected
OF, SF, ZF, AF, and PF as described in Appendix C.
Protected Mode Exceptions
#GP(0) if the result is a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
DIV ÄÄ Unsigned Divide
Opcode Instruction Clocks Description
F6 /6 DIV AL,r/m8 14/17 Unsigned divide AX by r/m byte
(AL=Quo, AH=Rem)
F7 /6 DIV AX,r/m16 22/25 Unsigned divide DX:AX by r/m
word (AX=Quo, DX=Rem)
F7 /6 DIV EAX,r/m32 38/41 Unsigned divide EDX:EAX by r/m
dword (EAX=Quo, EDX=Rem)
Operation
temp  dividend / divisor;
IF temp does not fit in quotient
THEN Interrupt 0;
ELSE
quotient  temp;
remainder  dividend MOD (r/m);
FI;
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Note:
Divisions are unsigned. The divisor is given by the r/m operand.
The dividend, quotient, and remainder use implicit registers. Refer to
the table under "Description."
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Description
DIV performs an unsigned division. The dividend is implicit; only the
divisor is given as an operand. The remainder is always less than the
divisor. The type of the divisor determines which registers to use as
follows:
Size Dividend Divisor Quotient Remainder
byte AX r/m8 AL AH
word DX:AX r/m16 AX DX
dword EDX:EAX r/m32 EAX EDX
Flags Affected
OF, SF, ZF, AR, PF, CF are undefined.
Protected Mode Exceptions
Interrupt 0 if the quotient is too large to fit in the designated register
(AL, AX, or EAX), or if the divisor is 0; #GP(0) for an illegal memory
operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0)
for an illegal address in the SS segment; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 0 if the quotient is too big to fit in the designated register
(AL, AX, or EAX), or if the divisor is 0; Interrupt 13 if any part of the
operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
ENTER ÄÄ Make Stack Frame for Procedure Parameters
Opcode Instruction Clocks Description
C8 iw 00 ENTER imm16,0 10 Make procedure stack frame
C8 iw 01 ENTER imm16,1 12 Make stack frame for procedure
parameters
C8 iw ib ENTER imm16,imm8 15+4(n-1) Make stack frame for
procedure parameters
Operation
level  level MOD 32
IF OperandSize = 16 THEN Push(BP) ELSE Push (EBP) FI;
(* Save stack pointer *)
frame-ptr  eSP
IF level > 0
THEN (* level is rightmost parameter *)
FOR i  1 TO level - 1
DO
IF OperandSize = 16
THEN
BP  BP - 2;
Push[BP]
ELSE (* OperandSize = 32 *)
EBP  EBP - 4;
Push[EBP];
FI;
OD;
Push(frame-ptr)
FI;
IF OperandSize = 16 THEN BP  frame-ptr ELSE EBP  frame-ptr; FI;
IF StackAddrSize = 16
THEN SP  SP - First operand;
ELSE ESP  ESP - ZeroExtend(First operand);
FI;
Description
ENTER creates the stack frame required by most block-structured
high-level languages. The first operand specifies the number of bytes of
dynamic storage allocated on the stack for the routine being entered.
The second operand gives the lexical nesting level (0 to 31) of the routine
within the high-level language source code. It determines the number of
stack frame pointers copied into the new stack frame from the preceding
frame. BP (or EBP, if the operand-size attribute is 32 bits) is the current
stack frame pointer.
If the operand-size attribute is 16 bits, the processor uses BP as the
frame pointer and SP as the stack pointer. If the operand-size attribute is
32 bits, the processor uses EBP for the frame pointer and ESP for the stack
pointer.
If the second operand is 0, ENTER pushes the frame pointer (BP or
EBP) onto the stack; ENTER then subtracts the first operand from the
stack pointer and sets the frame pointer to the current stack-pointer
value.
For example, a procedure with 12 bytes of local variables would have an
ENTER 12,0 instruction at its entry point and a LEAVE instruction
before every RET. The 12 local bytes would be addressed as negative
offsets from the frame pointer.
Flags Affected
None
Protected Mode Exceptions
#SS(0) if SP or ESP would exceed the stack limit at any point during
instruction execution; #PF(fault-code) for a page fault
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
HLT ÄÄ Halt
Opcode Instruction Clocks Description
F4 HLT 5 Halt
Operation
Enter Halt state;
Description
HALT stops instruction execution and places the 80386 in a HALT state.
An enabled interrupt, NMI, or a reset will resume execution. If an
interrupt (including NMI) is used to resume execution after HLT, the saved
CS:IP (or CS:EIP) value points to the instruction following HLT.
Flags Affected
None
Protected Mode Exceptions
HLT is a privileged instruction; #GP(0) if the current privilege level is
not 0
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
#GP(0); HLT is a privileged instruction
IDIV ÄÄ Signed Divide
Opcode Instruction Clocks Description
F6 /7 IDIV r/m8 19 Signed divide AX by r/m byte
(AL=Quo, AH=Rem)
F7 /7 IDIV AX,r/m16 27 Signed divide DX:AX by EA word
(AX=Quo, DX=Rem)
F7 /7 IDIV EAX,r/m32 43 Signed divide EDX:EAX by DWORD
byte (EAX=Quo, EDX=Rem)
Operation
temp  dividend / divisor;
IF temp does not fit in quotient
THEN Interrupt 0;
ELSE
quotient  temp;
remainder  dividend MOD (r/m);
FI;
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Notes:
Divisions are signed. The divisor is given by the r/m operand. The
dividend, quotient, and remainder use implicit registers. Refer to the
table under "Description."
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Description
IDIV performs a signed division. The dividend, quotient, and remainder
are implicitly allocated to fixed registers. Only the divisor is given as
an explicit r/m operand. The type of the divisor determines which registers
to use as follows:
Size Divisor Quotient Remainder Dividend
byte r/m8 AL AH AX
word r/m16 AX DX DX:AX
dword r/m32 EAX EDX EDX:EAX
If the resulting quotient is too large to fit in the destination, or if the
division is 0, an Interrupt 0 is generated. Nonintegral quotients are
truncated toward 0. The remainder has the same sign as the dividend
and the absolute value of the remainder is always less than the absolute
value of the divisor.
Flags Affected
OF, SF, ZF, AR, PF, CF are undefined.
Protected Mode Exceptions
Interrupt 0 if the quotient is too large to fit in the designated register
(AL or AX), or if the divisor is 0; #GP (0) for an illegal memory operand
effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an
illegal address in the SS segment; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 0 if the quotient is too large to fit in the designated register
(AL or AX), or if the divisor is 0; Interrupt 13 if any part of the operand
would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
IMUL ÄÄ Signed Multiply
Opcode Instruction Clocks Description
F6 /5 IMUL r/m8 9-14/12-17 AX AL * r/m byte
F7 /5 IMUL r/m16 9-22/12-25 DX:AX  AX * r/m word
F7 /5 IMUL r/m32 9-38/12-41 EDX:EAX  EAX * r/m dword
0F AF /r IMUL r16,r/m16 9-22/12-25 word register  word
register * r/m word
0F AF /r IMUL r32,r/m32 9-38/12-41 dword register  dword
register * r/m dword
6B /r ib IMUL r16,r/m16,imm8 9-14/12-17 word register  r/m16 *
sign-extended immediate byte
6B /r ib IMUL r32,r/m32,imm8 9-14/12-17 dword register  r/m32 *
sign-extended immediate byte
6B /r ib IMUL r16,imm8 9-14/12-17 word register  word
register * sign-extended
immediate byte
6B /r ib IMUL r32,imm8 9-14/12-17 dword register  dword
register * sign-extended
immediate byte
69 /r iw IMUL r16,r/m16,imm16 9-22/12-25 word register  r/m16 *
immediate word
69 /r id IMUL r32,r/m32,imm32 9-38/12-41 dword register  r/m32 *
immediate dword
69 /r iw IMUL r16,imm16 9-22/12-25 word register  r/m16 *
immediate word
69 /r id IMUL r32,imm32 9-38/12-41 dword register  r/m32 *
immediate dword
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
The 80386 uses an early-out multiply algorithm. The actual number of
clocks depends on the position of the most significant bit in the
optimizing multiplier, shown underlined above. The optimization occurs for
positive and negative values. Because of the early-out algorithm, clock
counts given are minimum to maximum. To calculate the actual clocks, use
the following formula:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Actual clock = if m <> 0 then max(ceiling(log{2} ³m³), 3) + 6 clocks
Actual clock = if m = 0 then 9 clocks
(where m is the multiplier)
Add three clocks if the multiplier is a memory operand.
Operation
result  multiplicand * multiplier;
Description
IMUL performs signed multiplication. Some forms of the instruction
use implicit register operands. The operand combinations for all forms
of the instruction are shown in the "Description" column above.
IMUL clears the overflow and carry flags under the following conditions:
Instruction Form Condition for Clearing CF and OF
r/m8 AL = sign-extend of AL to 16 bits
r/m16 AX = sign-extend of AX to 32 bits
r/m32 EDX:EAX = sign-extend of EAX to 32 bits
r16,r/m16 Result exactly fits within r16
r/32,r/m32 Result exactly fits within r32
r16,r/m16,imm16 Result exactly fits within r16
r32,r/m32,imm32 Result exactly fits within r32
Flags Affected
OF and CF as described above; SF, ZF, AF, and PF are undefined
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exeptions as in Real Address Mode; #PF(fault-code) for a page
fault
Notes
When using the accumulator forms (IMUL r/m8, IMUL r/m16, or IMUL
r/m32), the result of the multiplication is available even if the overflow
flag is set because the result is two times the size of the multiplicand
and multiplier. This is large enough to handle any possible result.
IN ÄÄ Input from Port
Opcode Instruction Clocks Description
E4 ib IN AL,imm8 12,pm=6*/26** Input byte from immediate port
into AL
E5 ib IN AX,imm8 12,pm=6*/26** Input word from immediate port
into AX
E5 ib IN EAX,imm8 12,pm=6*/26** Input dword from immediate port
into EAX
EC IN AL,DX 13,pm=7*/27** Input byte from port DX into AL
ED IN AX,DX 13,pm=7*/27** Input word from port DX into AX
ED IN EAX,DX 13,pm=7*/27** Input dword from port DX into
EAX
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
*If CPL ó IOPL
**If CPL > IOPL or if in virtual 8086 mode
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
IF NOT I-O-Permission (SRC, width(SRC))
THEN #GP(0);
FI;
FI;
DEST  [SRC]; (* Reads from I/O address space *)
Description
IN transfers a data byte or data word from the port numbered by the
second operand into the register (AL, AX, or EAX) specified by the first
operand. Access any port from 0 to 65535 by placing the port number
in the DX register and using an IN instruction with DX as the second
parameter. These I/O instructions can be shortened by using an 8-bit
port I/O in the instruction. The upper eight bits of the port address will
be 0 when 8-bit port I/O is used.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the current privilege level is larger (has less privilege) than
IOPL and any of the corresponding I/O permission bits in TSS equals 1
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
#GP(0) fault if any of the corresponding I/O permission bits in TSS
equals 1
INC ÄÄ Increment by 1
Opcode Instruction Clocks Description
FE /0 INC r/m8 Increment r/m byte by 1
FF /0 INC r/m16 Increment r/m word by 1
FF /6 INC r/m32 Increment r/m dword by 1
40 + rw INC r16 Increment word register by 1
40 + rd INC r32 Increment dword register by 1
Operation
DEST  DEST + 1;
Description
INC adds 1 to the operand. It does not change the carry flag. To affect
the carry flag, use the ADD instruction with a second operand of 1.
Flags Affected
OF, SF, ZF, AF, and PF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the operand is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
INS/INSB/INSW/INSD ÄÄ Input from Port to String
Opcode Instruction Clocks Description
6C INS r/m8,DX 15,pm=9*/29** Input byte from port DX into ES:(E)DI
6D INS r/m16,DX 15,pm=9*/29** Input word from port DX into ES:(E)DI
6D INS r/m32,DX 15,pm=9*/29** Input dword from port DX into ES:(E)DI
6C INSB 15,pm=9*/29** Input byte from port DX into ES:(E)DI
6D INSW 15,pm=9*/29** Input word from port DX into ES:(E)DI
6D INSD 15,pm=9*/29** Input dword from port DX into ES:(E)DI
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
*If CPL ó IOPL
**If CPL > IOPL or if in virtual 8086 mode
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
IF AddressSize = 16
THEN use DI for dest-index;
ELSE (* AddressSize = 32 *)
use EDI for dest-index;
FI;
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
IF NOT I-O-Permission (SRC, width(SRC))
THEN #GP(0);
FI;
FI;
IF byte type of instruction
THEN
ES:[dest-index]  [DX]; (* Reads byte at DX from I/O address space *)
IF DF = 0 THEN IncDec  1 ELSE IncDec  -1; FI;
FI;
IF OperandSize = 16
THEN
ES:[dest-index]  [DX]; (* Reads word at DX from I/O address space *)
IF DF = 0 THEN IncDec  2 ELSE IncDec  -2; FI;
FI;
IF OperandSize = 32
THEN
ES:[dest-index]  [DX]; (* Reads dword at DX from I/O address space *)
IF DF = 0 THEN IncDec  4 ELSE IncDec  -4; FI;
FI;
dest-index  dest-index + IncDec;
Description
INS transfers data from the input port numbered by the DX register to
the memory byte or word at ES:dest-index. The memory operand must
be addressable from ES; no segment override is possible. The destination
register is DI if the address-size attribute of the instruction is 16 bits,
or EDI if the address-size attribute is 32 bits.
INS does not allow the specification of the port number as an immediate
value. The port must be addressed through the DX register value. Load
the correct value into DX before executing the INS instruction.
The destination address is determined by the contents of the destination
index register. Load the correct index into the destination index register
before executing INS.
After the transfer is made, DI or EDI advances automatically. If the
direction flag is 0 (CLD was executed), DI or EDI increments; if the
direction flag is 1 (STD was executed), DI or EDI decrements. DI
increments or decrements by 1 if a byte is input, by 2 if a word is input,
or by 4 if a doubleword is input.
INSB, INSW and INSD are synonyms of the byte, word, and doubleword
INS instructions. INS can be preceded by the REP prefix for block input of
CX bytes or words. Refer to the REP instruction for details of this
operation.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if CPL is numerically greater than IOPL and any of the
corresponding I/O permission bits in TSS equals 1; #GP(0) if the
destination is in a nonwritable segment; #GP(0) for an illegal memory
operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for
an illegal address in the SS segment; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
#GP(0) fault if any of the corresponding I/O permission bits in TSS
equals 1; #PF(fault-code) for a page fault
INT/INTO ÄÄ Call to Interrupt Procedure
Opcode Instruction Clocks Description
CC INT 3 33 Interrupt 3--trap to debugger
CC INT 3 pm=59 Interrupt 3--Protected Mode, same
privilege
CC INT 3 pm=99 Interrupt 3--Protected Mode, more
privilege
CC INT 3 pm=119 Interrupt 3--from V86 mode to PL 0
CC INT 3 ts Interrupt 3--Protected Mode, via
task gate
CD ib INT imm8 37 Interrupt numbered by immediate
byte
CD ib INT imm8 pm=59 Interrupt--Protected Mode, same
privilege
CD ib INT imm8 pm=99 Interrupt--Protected Mode, more
privilege
CD ib INT imm8 pm=119 Interrupt--from V86 mode to PL 0
CD ib INT imm8 ts Interrupt--Protected Mode, via task
gate
CE INTO Fail:3,pm=3;
Pass:35 Interrupt 4--if overflow flag is 1
CE INTO pm=59 Interrupt 4--Protected Mode, same
privilege
CE INTO pm=99 Interrupt 4--Protected Mode, more
privilege
CE INTO pm=119 Interrupt 4--from V86 mode to PL 0
CE INTO ts Interrupt 4--Protected Mode, via
task gate
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTE:
Approximate values of ts are given by the following table:
New Task
Old Task 386 TSS 386 TSS 286 TSS
VM = 0 VM = 1
386
TSS VM=0 309 226 282
386
TSS VM=1 314 231 287
286
TSS 307 224 280
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTE:
The following operational description applies not only to the
above instructions but also to external interrupts and exceptions.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF PE = 0
THEN GOTO REAL-ADDRESS-MODE;
ELSE GOTO PROTECTED-MODE;
FI;
REAL-ADDRESS-MODE:
Push (FLAGS);
IF  0; (* Clear interrupt flag *)
TF  0; (* Clear trap flag *)
Push(CS);
Push(IP);
(* No error codes are pushed *)
CS  IDT[Interrupt number * 4].selector;
IP  IDT[Interrupt number * 4].offset;
PROTECTED-MODE:
Interrupt vector must be within IDT table limits,
else #GP(vector number * 8+2+EXT);
Descriptor AR byte must indicate interrupt gate, trap gate, or task gate,
else #GP(vector number * 8+2+EXT);
IF software interrupt (* i.e. caused by INT n, INT 3, or INTO *)
THEN
IF gate descriptor DPL < CPL
THEN #GP(vector number * 8+2+EXT);
FI;
FI;
Gate must be present, else #NP(vector number * 8+2+EXT);
IF trap gate OR interrupt gate
THEN GOTO TRAP-GATE-OR-INTERRUPT-GATE;
ELSE GOTO TASK-GATE;
FI;
TRAP-GATE-OR-INTERRUPT-GATE:
Examine CS selector and descriptor given in the gate descriptor;
Selector must be non-null, else #GP (EXT);
Selector must be within its descriptor table limits
ELSE #GP(selector+EXT);
Descriptor AR byte must indicate code segment
ELSE #GP(selector + EXT);
Segment must be present, else #NP(selector+EXT);
IF code segment is non-conforming AND DPL < CPL
THEN GOTO INTERRUPT-TO-INNER-PRIVILEGE;
ELSE
IF code segment is conforming OR code segment DPL = CPL
THEN GOTO INTERRUPT-TO-SAME-PRIVILEGE-LEVEL;
ELSE #GP(CS selector + EXT);
FI;
FI;
INTERRUPT-TO-INNER-PRIVILEGE:
Check selector and descriptor for new stack in current TSS;
Selector must be non-null, else #GP(EXT);
Selector index must be within its descriptor table limits
ELSE #TS(SS selector+EXT);
Selector's RPL must equal DPL of code segment, else #TS(SS
selector+EXT);
Stack segment DPL must equal DPL of code segment, else #TS(SS
selector+EXT);
Descriptor must indicate writable data segment, else #TS(SS
selector+EXT);
Segment must be present, else #SS(SS selector+EXT);
IF 32-bit gate
THEN New stack must have room for 20 bytes else #SS(0)
ELSE New stack must have room for 10 bytes else #SS(0)
FI;
Instruction pointer must be within CS segment boundaries else #GP(0);
Load new SS and eSP value from TSS;
IF 32-bit gate
THEN CS:EIP  selector:offset from gate;
ELSE CS:IP  selector:offset from gate;
FI;
Load CS descriptor into invisible portion of CS register;
Load SS descriptor into invisible portion of SS register;
IF 32-bit gate
THEN
Push (long pointer to old stack) (* 3 words padded to 4 *);
Push (EFLAGS);
Push (long pointer to return location) (* 3 words padded to 4*);
ELSE
Push (long pointer to old stack) (* 2 words *);
Push (FLAGS);
Push (long pointer to return location) (* 2 words *);
FI;
Set CPL to new code segment DPL;
Set RPL of CS to CPL;
IF interrupt gate THEN IF  0 (* interrupt flag to 0 (disabled) *); FI;
TF  0;
NT  0;
INTERRUPT-FROM-V86-MODE:
TempEFlags  EFLAGS;
VM  0;
TF  0;
IF service through Interrupt Gate THEN IF  0;
TempSS  SS;
TempESP  ESP;
SS  TSS.SS0; (* Change to level 0 stack segment *)
ESP  TSS.ESP0; (* Change to level 0 stack pointer *)
Push(GS); (* padded to two words *)
Push(FS); (* padded to two words *)
Push(DS); (* padded to two words *)
Push(ES); (* padded to two words *)
GS  0;
FS  0;
DS  0;
ES  0;
Push(TempSS); (* padded to two words *)
Push(TempESP);
Push(TempEFlags);
Push(CS); (* padded to two words *)
Push(EIP);
CS:EIP  selector:offset from interrupt gate;
(* Starts execution of new routine in 80386 Protected Mode *)
INTERRUPT-TO-SAME-PRIVILEGE-LEVEL:
IF 32-bit gate
THEN Current stack limits must allow pushing 10 bytes, else #SS(0);
ELSE Current stack limits must allow pushing 6 bytes, else #SS(0);
FI;
IF interrupt was caused by exception with error code
THEN Stack limits must allow push of two more bytes;
ELSE #SS(0);
FI;
Instruction pointer must be in CS limit, else #GP(0);
IF 32-bit gate
THEN
Push (EFLAGS);
Push (long pointer to return location); (* 3 words padded to 4 *)
CS:EIP  selector:offset from gate;
ELSE (* 16-bit gate *)
Push (FLAGS);
Push (long pointer to return location); (* 2 words *)
CS:IP  selector:offset from gate;
FI;
Load CS descriptor into invisible portion of CS register;
Set the RPL field of CS to CPL;
Push (error code); (* if any *)
IF interrupt gate THEN IF  0; FI;
TF  0;
NT  0;
TASK-GATE:
Examine selector to TSS, given in task gate descriptor;
Must specify global in the local/global bit, else #TS(TSS selector);
Index must be within GDT limits, else #TS(TSS selector);
AR byte must specify available TSS (bottom bits 00001),
else #TS(TSS selector;
TSS must be present, else #NP(TSS selector);
SWITCH-TASKS with nesting to TSS;
IF interrupt was caused by fault with error code
THEN
Stack limits must allow push of two more bytes, else #SS(0);
Push error code onto stack;
FI;
Instruction pointer must be in CS limit, else #GP(0);
Description
The INT instruction generates via software a call to an interrupt
handler. The immediate operand, from 0 to 255, gives the index number
into the Interrupt Descriptor Table (IDT) of the interrupt routine to be
called. In Protected Mode, the IDT consists of an array of eight-byte
descriptors; the descriptor for the interrupt invoked must indicate an
interrupt, trap, or task gate. In Real Address Mode, the IDT is an array
of four byte-long pointers. In Protected and Real Address Modes, the
base linear address of the IDT is defined by the contents of the IDTR.
The INTO conditional software instruction is identical to the INT
interrupt instruction except that the interrupt number is implicitly 4,
and the interrupt is made only if the 80386 overflow flag is set.
The first 32 interrupts are reserved by Intel for system use. Some of
these interrupts are use for internally generated exceptions.
INT n generally behaves like a far call except that the flags register is
pushed onto the stack before the return address. Interrupt procedures
return via the IRET instruction, which pops the flags and return address
from the stack.
In Real Address Mode, INT n pushes the flags, CS, and the return IP
onto the stack, in that order, then jumps to the long pointer indexed by
the interrupt number.
Flags Affected
None
Protected Mode Exceptions
#GP, #NP, #SS, and #TS as indicated under "Operation" above
Real Address Mode Exceptions
None; if the SP or ESP = 1, 3, or 5 before executing INT or INTO,
the 80386 will shut down due to insufficient stack space
Virtual 8086 Mode Exceptions
#GP(0) fault if IOPL is less than 3, for INT only, to permit emulation;
Interrupt 3 (0CCH) generates Interrupt 3; INTO generates Interrupt 4
if the overflow flag equals 1
IRET/IRETD ÄÄ Interrupt Return
Opcode Instruction Clocks Description
CF IRET 22,pm=38 Interrupt return (far return and pop
flags)
CF IRET pm=82 Interrupt return to lesser privilege
CF IRET ts Interrupt return, different task (NT = 1)
CF IRETD 22,pm=38 Interrupt return (far return and pop
flags)
CF IRETD pm=82 Interrupt return to lesser privilege
CF IRETD pm=60 Interrupt return to V86 mode
CF IRETD ts Interrupt return, different task (NT = 1)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTE:
Values of ts are given by the following table:
New Task
Old Task 386 TSS 386 TSS 286 TSS
VM = 0 VM = 1
386
TSS VM=0 275 224 271
286
TSS 265 214 232
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
IF PE = 0
THEN (* Real-address mode *)
IF OperandSize = 32 (* Instruction = IRETD *)
THEN EIP  Pop();
ELSE (* Instruction = IRET *)
IP  Pop();
FI;
CS  Pop();
IF OperandSize = 32 (* Instruction = IRETD *)
THEN EFLAGS  Pop();
ELSE (* Instruction = IRET *)
FLAGS  Pop();
FI;
ELSE (* Protected mode *)
IF VM = 1
THEN #GP(0);
ELSE
IF NT = 1
THEN GOTO TASK-RETURN;
ELSE
IF VM = 1 in flags image on stack
THEN GO TO STACK-RETURN-TO-V86;
ELSE GOTO STACK-RETURN;
FI;
FI;
FI;
FI;STACK-RETURN-TO-V86: (* Interrupted procedure was in V86 mode *)
IF return CS selector RPL < > 3
THEN #GP(Return selector);
FI;
IF top 36 bytes of stack not within limits
THEN #SS(0);
FI;
Examine return CS selector and associated descriptor:
IF selector is null, THEN #GP(0); FI;
IF selector index not within its descriptor table limits;
THEN #GP(Return selector);
FI;
IF AR byte does not indicate code segment
THEN #GP(Return selector);
FI;
IF code segment DPL not = 3;
THEN #GP(Return selector);
FI;
IF code segment not present
THEN #NP(Return selector);
FI;
Examine return SS selector and associated descriptor:
IF selector is null THEN #GP(0); FI;
IF selector index not within its descriptor table limits
THEN #GP(SS selector);
FI;
IF selector RPL not = RPL of return CS selector
THEN #GP(SS selector);
FI;
IF AR byte does not indicate a writable data segment
THEN #GP(SS selector);
FI;
IF stack segment DPL not = RPL of return CS selector
THEN #GP(SS selector);
FI;
IF SS not present
THEN #NP(SS selector);
FI;
IF instruction pointer not within code segment limit THEN #GP(0);
FI;
EFLAGS  SS:[eSP + 8]; (* Sets VM in interrupted routine *)
EIP  Pop();
CS  Pop(); (* CS behaves as in 8086, due to VM = 1 *)
throwaway  Pop(); (* pop away EFLAGS already read *)
ES  Pop(); (* pop 2 words; throw away high-order word *)
DS  Pop(); (* pop 2 words; throw away high-order word *)
FS  Pop(); (* pop 2 words; throw away high-order word *)
GS  Pop(); (* pop 2 words; throw away high-order word *)
IF CS.RPL > CPL
THEN
TempESP  Pop();
TempSS  Pop();
SS:ESP  TempSS:TempESP;
FI;
(* Resume execution in Virtual 8086 mode *)
TASK-RETURN:
Examine Back Link Selector in TSS addressed by the current task
register:
Must specify global in the local/global bit, else #TS(new TSS
selector);
Index must be within GDT limits, else #TS(new TSS selector);
AR byte must specify TSS, else #TS(new TSS selector);
New TSS must be busy, else #TS(new TSS selector);
TSS must be present, else #NP(new TSS selector);
SWITCH-TASKS without nesting to TSS specified by back link selector;
Mark the task just abandoned as NOT BUSY;
Instruction pointer must be within code segment limit ELSE #GP(0);
STACK-RETURN:
IF OperandSize=32
THEN Third word on stack must be within stack limits, else #SS(0);
ELSE Second word on stack must be within stack limits, else #SS(0);
FI;
Return CS selector RPL must be ò CPL, else #GP(Return selector);
IF return selector RPL = CPL
THEN GOTO RETURN-SAME-LEVEL;
ELSE GOTO RETURN-OUTER-LEVEL;
FI;
RETURN-SAME-LEVEL:
IF OperandSize=32
THEN
Top 12 bytes on stack must be within limits, else #SS(0);
Return CS selector (at eSP+4) must be non-null, else #GP(0);
ELSE
Top 6 bytes on stack must be within limits, else #SS(0);
Return CS selector (at eSP+2) must be non-null, else #GP(0);
FI;
Selector index must be within its descriptor table limits, else #GP
(Return selector);
AR byte must indicate code segment, else #GP(Return selector);
IF non-conforming
THEN code segment DPL must = CPL;
ELSE #GP(Return selector);
FI;
IF conforming
THEN code segment DPL must be ó CPL, else #GP(Return selector);
Segment must be present, else #NP(Return selector);
Instruction pointer must be within code segment boundaries, else #GP(0);
FI;
IF OperandSize=32
THEN
Load CS:EIP from stack;
Load CS-register with new code segment descriptor;
Load EFLAGS with third doubleword from stack;
Increment eSP by 12;
ELSE
Load CS-register with new code segment descriptor;
Load FLAGS with third word on stack;
Increment eSP by 6;
FI;
RETURN-OUTER-LEVEL:
IF OperandSize=32
THEN Top 20 bytes on stack must be within limits, else #SS(0);
ELSE Top 10 bytes on stack must be within limits, else #SS(0);
FI;
Examine return CS selector and associated descriptor:
Selector must be non-null, else #GP(0);
Selector index must be within its descriptor table limits;
ELSE #GP(Return selector);
AR byte must indicate code segment, else #GP(Return selector);
IF non-conforming
THEN code segment DPL must = CS selector RPL;
ELSE #GP(Return selector);
FI;
IF conforming
THEN code segment DPL must be > CPL;
ELSE #GP(Return selector);
FI;
Segment must be present, else #NP(Return selector);
Examine return SS selector and associated descriptor:
Selector must be non-null, else #GP(0);
Selector index must be within its descriptor table limits
ELSE #GP(SS selector);
Selector RPL must equal the RPL of the return CS selector
ELSE #GP(SS selector);
AR byte must indicate a writable data segment, else #GP(SS selector);
Stack segment DPL must equal the RPL of the return CS selector
ELSE #GP(SS selector);
SS must be present, else #NP(SS selector);
Instruction pointer must be within code segment limit ELSE #GP(0);
IF OperandSize=32
THEN
Load CS:EIP from stack;
Load EFLAGS with values at (eSP+8);
ELSE
Load CS:IP from stack;
Load FLAGS with values at (eSP+4);
FI;
Load SS:eSP from stack;
Set CPL to the RPL of the return CS selector;
Load the CS register with the CS descriptor;
Load the SS register with the SS descriptor;
FOR each of ES, FS, GS, and DS
DO;
IF the current value of the register is not valid for the outer level;
THEN zero the register and clear the valid flag;
FI;
To be valid, the register setting must satisfy the following
properties:
Selector index must be within descriptor table limits;
AR byte must indicate data or readable code segment;
IF segment is data or non-conforming code,
THEN DPL must be ò CPL, or DPL must be ò RPL;
OD;
Description
In Real Address Mode, IRET pops the instruction pointer, CS, and the
flags register from the stack and resumes the interrupted routine.
In Protected Mode, the action of IRET depends on the setting of the
nested task flag (NT) bit in the flag register. When popping the new
flag image from the stack, the IOPL bits in the flag register are changed
only when CPL equals 0.
If NT equals 0, IRET returns from an interrupt procedure without a
task switch. The code returned to must be equally or less privileged than
the interrupt routine (as indicated by the RPL bits of the CS selector
popped from the stack). If the destination code is less privileged, IRET
also pops the stack pointer and SS from the stack.
If NT equals 1, IRET reverses the operation of a CALL or INT that
caused a task switch. The updated state of the task executing IRET is
saved in its task state segment. If the task is reentered later, the code
that follows IRET is executed.
Flags Affected
All; the flags register is popped from stack
Protected Mode Exceptions
#GP, #NP, or #SS, as indicated under "Operation" above
Real Address Mode Exceptions
Interrupt 13 if any part of the operand being popped lies beyond address
0FFFFH
Virtual 8086 Mode Exceptions
#GP(0) fault if IOPL is less than 3, to permit emulation
Jcc ÄÄ Jump if Condition is Met
Opcode Instruction Clocks Description
77 cb JA rel8 7+m,3 Jump short if above (CF=0 and
ZF=0)
73 cb JAE rel8 7+m,3 Jump short if above or equal
(CF=0)
72 cb JB rel8 7+m,3 Jump short if below (CF=1)
76 cb JBE rel8 7+m,3 Jump short if below or equal
(CF=1 or ZF=1)
72 cb JC rel8 7+m,3 Jump short if carry (CF=1)
E3 cb JCXZ rel8 9+m,5 Jump short if CX register is 0
E3 cb JECXZ rel8 9+m,5 Jump short if ECX register is 0
74 cb JE rel8 7+m,3 Jump short if equal (ZF=1)
74 cb JZ rel8 7+m,3 Jump short if 0 (ZF=1)
7F cb JG rel8 7+m,3 Jump short if greater (ZF=0 and
SF=OF)
7D cb JGE rel8 7+m,3 Jump short if greater or equal
(SF=OF)
7C cb JL rel8 7+m,3 Jump short if less (SF<>OF)
7E cb JLE rel8 7+m,3 Jump short if less or equal
(ZF=1 and SF<>OF)
76 cb JNA rel8 7+m,3 Jump short if not above (CF=1 or
ZF=1)
72 cb JNAE rel8 7+m,3 Jump short if not above or equal
(CF=1)
73 cb JNB rel8 7+m,3 Jump short if not below (CF=0)
77 cb JNBE rel8 7+m,3 Jump short if not below or equal
(CF=0 and ZF=0)
73 cb JNC rel8 7+m,3 Jump short if not carry (CF=0)
75 cb JNE rel8 7+m,3 Jump short if not equal (ZF=0)
7E cb JNG rel8 7+m,3 Jump short if not greater (ZF=1
or SF<>OF)
7C cb JNGE rel8 7+m,3 Jump short if not greater or
equal (SF<>OF)
7D cb JNL rel8 7+m,3 Jump short if not less (SF=OF)
7F cb JNLE rel8 7+m,3 Jump short if not less or equal
(ZF=0 and SF=OF)
71 cb JNO rel8 7+m,3 Jump short if not overflow
(OF=0)
7B cb JNP rel8 7+m,3 Jump short if not parity (PF=0)
79 cb JNS rel8 7+m,3 Jump short if not sign (SF=0)
75 cb JNZ rel8 7+m,3 Jump short if not zero (ZF=0)
70 cb JO rel8 7+m,3 Jump short if overflow (OF=1)
7A cb JP rel8 7+m,3 Jump short if parity (PF=1)
7A cb JPE rel8 7+m,3 Jump short if parity even (PF=1)
7B cb JPO rel8 7+m,3 Jump short if parity odd (PF=0)
78 cb JS rel8 7+m,3 Jump short if sign (SF=1)
74 cb JZ rel8 7+m,3 Jump short if zero (ZF = 1)
0F 87 cw/cd JA rel16/32 7+m,3 Jump near if above (CF=0 and
ZF=0)
0F 83 cw/cd JAE rel16/32 7+m,3 Jump near if above or equal
(CF=0)
0F 82 cw/cd JB rel16/32 7+m,3 Jump near if below (CF=1)
0F 86 cw/cd JBE rel16/32 7+m,3 Jump near if below or equal
(CF=1 or ZF=1)
0F 82 cw/cd JC rel16/32 7+m,3 Jump near if carry (CF=1)
0F 84 cw/cd JE rel16/32 7+m,3 Jump near if equal (ZF=1)
0F 84 cw/cd JZ rel16/32 7+m,3 Jump near if 0 (ZF=1)
0F 8F cw/cd JG rel16/32 7+m,3 Jump near if greater (ZF=0 and
SF=OF)
0F 8D cw/cd JGE rel16/32 7+m,3 Jump near if greater or equal
(SF=OF)
0F 8C cw/cd JL rel16/32 7+m,3 Jump near if less (SF<>OF)
0F 8E cw/cd JLE rel16/32 7+m,3 Jump near if less or equal (ZF=1
and SF<>OF)
0F 86 cw/cd JNA rel16/32 7+m,3 Jump near if not above (CF=1 or
ZF=1)
0F 82 cw/cd JNAE rel16/32 7+m,3 Jump near if not above or equal
(CF=1)
0F 83 cw/cd JNB rel16/32 7+m,3 Jump near if not below (CF=0)
0F 87 cw/cd JNBE rel16/32 7+m,3 Jump near if not below or equal
(CF=0 and ZF=0)
0F 83 cw/cd JNC rel16/32 7+m,3 Jump near if not carry (CF=0)
0F 85 cw/cd JNE rel16/32 7+m,3 Jump near if not equal (ZF=0)
0F 8E cw/cd JNG rel16/32 7+m,3 Jump near if not greater (ZF=1
or SF<>OF)
0F 8C cw/cd JNGE rel16/32 7+m,3 Jump near if not greater or
equal (SF<>OF)
0F 8D cw/cd JNL rel16/32 7+m,3 Jump near if not less (SF=OF)
0F 8F cw/cd JNLE rel16/32 7+m,3 Jump near if not less or equal
(ZF=0 and SF=OF)
0F 81 cw/cd JNO rel16/32 7+m,3 Jump near if not overflow (OF=0)
0F 8B cw/cd JNP rel16/32 7+m,3 Jump near if not parity (PF=0)
0F 89 cw/cd JNS rel16/32 7+m,3 Jump near if not sign (SF=0)
0F 85 cw/cd JNZ rel16/32 7+m,3 Jump near if not zero (ZF=0)
0F 80 cw/cd JO rel16/32 7+m,3 Jump near if overflow (OF=1)
0F 8A cw/cd JP rel16/32 7+m,3 Jump near if parity (PF=1)
0F 8A cw/cd JPE rel16/32 7+m,3 Jump near if parity even (PF=1)
0F 8B cw/cd JPO rel16/32 7+m,3 Jump near if parity odd (PF=0)
0F 88 cw/cd JS rel16/32 7+m,3 Jump near if sign (SF=1)
0F 84 cw/cd JZ rel16/32 7+m,3 Jump near if 0 (ZF=1)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
The first clock count is for the true condition (branch taken); the
second clock count is for the false condition (branch not taken). rel16/32
indicates that these instructions map to two; one with a 16-bit relative
displacement, the other with a 32-bit relative displacement, depending on
the operand-size attribute of the instruction.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
IF condition
THEN
EIP  EIP + SignExtend(rel8/16/32);
IF OperandSize = 16
THEN EIP  EIP AND 0000FFFFH;
FI;
FI;
Description
Conditional jumps (except JCXZ) test the flags which have been set by
a previous instruction. The conditions for each mnemonic are given in
parentheses after each description above. The terms "less" and "greater"
are used for comparisons of signed integers; "above" and "below" are
used for unsigned integers.
If the given condition is true, a jump is made to the location provided as
the operand. Instruction coding is most efficient when the target for the
conditional jump is in the current code segment and within -128 to
+127 bytes of the next instruction's first byte. The jump can also target
-32768 thru +32767 (segment size attribute 16) or -2^(31) thru +2^(31) -1
(segment size attribute 32) relative to the next instruction's first byte.
When the target for the conditional jump is in a different segment, use
the opposite case of the jump instruction (i.e., JE and JNE), and then
access the target with an unconditional far jump to the other segment.
For example, you cannot codeÄÄ
JZ FARLABEL;
You must instead codeÄÄ
JNZ BEYOND;
JMP FARLABEL;
BEYOND:
Because there can be several ways to interpret a particular state of the
flags, ASM386 provides more than one mnemonic for most of the
conditional jump opcodes. For example, if you compared two characters in
AX and want to jump if they are equal, use JE; or, if you ANDed AX
with a bit field mask and only want to jump if the result is 0, use JZ, a
synonym for JE.
JCXZ differs from other conditional jumps because it tests the contents of
the CX or ECX register for 0, not the flags. JCXZ is useful at the beginning
of a conditional loop that terminates with a conditional loop instruction
(such as LOOPNE TARGET LABEL. The JCXZ prevents entering the loop with CX or
ECX equal to zero, which would cause the loop to execute 64K or 32G times
instead of zero times.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the offset jumped to is beyond the limits of the code segment
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
JMP ÄÄ Jump
Opcode Instruction Clocks Description
EB cb JMP rel8 7+m Jump short
E9 cw JMP rel16 7+m Jump near, displacement relative
to next instruction
FF /4 JMP r/m16 7+m/10+m Jump near indirect
EA cd JMP ptr16:16 12+m,pm=27+m Jump intersegment, 4-byte
immediate address
EA cd JMP ptr16:16 pm=45+m Jump to call gate, same
privilege
EA cd JMP ptr16:16 ts Jump via task state segment
EA cd JMP ptr16:16 ts Jump via task gate
FF /5 JMP m16:16 43+m,pm=31+m Jump r/m16:16 indirect and
intersegment
FF /5 JMP m16:16 pm=49+m Jump to call gate, same
privilege
FF /5 JMP m16:16 5 + ts Jump via task state segment
FF /5 JMP m16:16 5 + ts Jump via task gate
E9 cd JMP rel32 7+m Jump near, displacement relative
to next instruction
FF /4 JMP r/m32 7+m,10+m Jump near, indirect
EA cp JMP ptr16:32 12+m,pm=27+m Jump intersegment, 6-byte
immediate address
EA cp JMP ptr16:32 pm=45+m Jump to call gate, same
privilege
EA cp JMP ptr16:32 ts Jump via task state segment
EA cp JMP ptr16:32 ts Jump via task gate
FF /5 JMP m16:32 43+m,pm=31+m Jump intersegment, address at
r/m dword
FF /5 JMP m16:32 pm=49+m Jump to call gate, same
privilege
FF /5 JMP m16:32 5 + ts Jump via task state segment
FF /5 JMP m16:32 5 + ts Jump via task gate
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTE:
Values of ts are given by the following table:
New Task
386 TSS 386 TASK 286 TSS
VM = 0 VM = 1
Old Task Via Task Gate?
N Y N Y N Y
386
TSS VM=0 303 312 220 229 276 285
286
TSS 301 310 218 227 274 283
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
IF instruction = relative JMP
(* i.e. operand is rel8, rel16, or rel32 *)
THEN
EIP  EIP + rel8/16/32;
IF OperandSize = 16
THEN EIP  EIP AND 0000FFFFH;
FI;
FI;
IF instruction = near indirect JMP
(* i.e. operand is r/m16 or r/m32 *)
THEN
IF OperandSize = 16
THEN
EIP  [r/m16] AND 0000FFFFH;
ELSE (* OperandSize = 32 *)
EIP  [r/m32];
FI;
FI;
IF (PE = 0 OR (PE = 1 AND VM = 1)) (* real mode or V86 mode *)
AND instruction = far JMP
(* i.e., operand type is m16:16, m16:32, ptr16:16, ptr16:32 *)
THEN GOTO REAL-OR-V86-MODE;
IF operand type = m16:16 or m16:32
THEN (* indirect *)
IF OperandSize = 16
THEN
CS:IP  [m16:16];
EIP  EIP AND 0000FFFFH; (* clear upper 16 bits *)
ELSE (* OperandSize = 32 *)
CS:EIP  [m16:32];
FI;
FI;
IF operand type = ptr16:16 or ptr16:32
THEN
IF OperandSize = 16
THEN
CS:IP  ptr16:16;
EIP  EIP AND 0000FFFFH; (* clear upper 16 bits *)
ELSE (* OperandSize = 32 *)
CS:EIP  ptr16:32;
FI;
FI;
FI;
IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)
AND instruction = far JMP
THEN
IF operand type = m16:16 or m16:32
THEN (* indirect *)
check access of EA dword;
#GP(0) or #SS(0) IF limit violation;
FI;
Destination selector is not null ELSE #GP(0)
Destination selector index is within its descriptor table limits ELSE
#GP(selector)
Depending on AR byte of destination descriptor:
GOTO CONFORMING-CODE-SEGMENT;
GOTO NONCONFORMING-CODE-SEGMENT;
GOTO CALL-GATE;
GOTO TASK-GATE;
GOTO TASK-STATE-SEGMENT;
ELSE #GP(selector); (* illegal AR byte in descriptor *)
FI;
CONFORMING-CODE-SEGMENT:
Descriptor DPL must be ó CPL ELSE #GP(selector);
Segment must be present ELSE #NP(selector);
Instruction pointer must be within code-segment limit ELSE #GP(0);
IF OperandSize = 32
THEN Load CS:EIP from destination pointer;
ELSE Load CS:IP from destination pointer;
FI;
Load CS register with new segment descriptor;
NONCONFORMING-CODE-SEGMENT:
RPL of destination selector must be ó CPL ELSE #GP(selector);
Descriptor DPL must be = CPL ELSE #GP(selector);
Segment must be present ELSE # NP(selector);
Instruction pointer must be within code-segment limit ELSE #GP(0);
IF OperandSize = 32
THEN Load CS:EIP from destination pointer;
ELSE Load CS:IP from destination pointer;
FI;
Load CS register with new segment descriptor;
Set RPL field of CS register to CPL;
CALL-GATE:
Descriptor DPL must be ò CPL ELSE #GP(gate selector);
Descriptor DPL must be ò gate selector RPL ELSE #GP(gate selector);
Gate must be present ELSE #NP(gate selector);
Examine selector to code segment given in call gate descriptor:
Selector must not be null ELSE #GP(0);
Selector must be within its descriptor table limits ELSE
#GP(CS selector);
Descriptor AR byte must indicate code segment
ELSE #GP(CS selector);
IF non-conforming
THEN code-segment descriptor, DPL must = CPL
ELSE #GP(CS selector);
FI;
IF conforming
THEN code-segment descriptor DPL must be ó CPL;
ELSE #GP(CS selector);
Code segment must be present ELSE #NP(CS selector);
Instruction pointer must be within code-segment limit ELSE #GP(0);
IF OperandSize = 32
THEN Load CS:EIP from call gate;
ELSE Load CS:IP from call gate;
FI;
Load CS register with new code-segment descriptor;
Set RPL of CS to CPL
TASK-GATE:
Gate descriptor DPL must be ò CPL ELSE #GP(gate selector);
Gate descriptor DPL must be ò gate selector RPL ELSE #GP(gate
selector);
Task Gate must be present ELSE #NP(gate selector);
Examine selector to TSS, given in Task Gate descriptor:
Must specify global in the local/global bit ELSE #GP(TSS selector);
Index must be within GDT limits ELSE #GP(TSS selector);
Descriptor AR byte must specify available TSS (bottom bits 00001);
ELSE #GP(TSS selector);
Task State Segment must be present ELSE #NP(TSS selector);
SWITCH-TASKS (without nesting) to TSS;
Instruction pointer must be within code-segment limit ELSE #GP(0);
TASK-STATE-SEGMENT:
TSS DPL must be ò CPL ELSE #GP(TSS selector);
TSS DPL must be ò TSS selector RPL ELSE #GP(TSS selector);
Descriptor AR byte must specify available TSS (bottom bits 00001)
ELSE #GP(TSS selector);
Task State Segment must be present ELSE #NP(TSS selector);
SWITCH-TASKS (without nesting) to TSS;
Instruction pointer must be within code-segment limit ELSE #GP(0);
Description
The JMP instruction transfers control to a different point in the
instruction stream without recording return information.
The action of the various forms of the instruction are shown below.
Jumps with destinations of type r/m16, r/m32, rel16, and rel32 are near
jumps and do not involve changing the segment register value.
The JMP rel16 and JMP rel32 forms of the instruction add an offset to
the address of the instruction following the JMP to determine the
destination. The rel16 form is used when the instruction's operand-size
attribute is 16 bits (segment size attribute 16 only); rel32 is used when
the operand-size attribute is 32 bits (segment size attribute 32 only). The
result is stored in the 32-bit EIP register. With rel16, the upper 16 bits
of EIP are cleared, which results in an offset whose value does not exceed
16 bits.
JMP r/m16 and JMP r/m32 specifies a register or memory location from which
the absolute offset from the procedure is fetched. The offset fetched from
r/m is 32 bits for an operand-size attribute of 32 bits (r/m32), or 16 bits
for an operand-size attribute of 16 bits (r/m16).
The JMP ptr16:16 and ptr16:32 forms of the instruction use a four-byte
or six-byte operand as a long pointer to the destination. The JMP
and forms fetch the long pointer from the memory location
specified (indirection). In Real Address Mode or Virtual 8086 Mode,
the long pointer provides 16 bits for the CS register and 16 or 32 bits
for the EIP register (depending on the operand-size attribute). In
Protected Mode, both long pointer forms consult the Access Rights (AR)
byte in the descriptor indexed by the selector part of the long pointer.
Depending on the value of the AR byte, the jump will perform one of
the following types of control transfers:
þ A jump to a code segment at the same privilege level
þ A task switch
For more information on protected mode control transfers, refer to
Chapter 6 and Chapter 7.
Flags Affected
All if a task switch takes place; none if no task switch occurs
Protected Mode Exceptions
Far jumps: #GP, #NP, #SS, and #TS, as indicated in the list above.
Near direct jumps: #GP(0) if procedure location is beyond the code
segment limits.
Near indirect jumps: #GP(0) for an illegal memory operand effective
address in the CS, DS, ES, FS, or GS segments: #SS(0) for an illegal
address in the SS segment; #GP if the indirect offset obtained is beyond
the code segment limits; #PF(fault-code) for a page fault.
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would be outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as under Real Address Mode; #PF(fault-code) for a
page fault
LAHF ÄÄ Load Flags into AH Register
Opcode Instruction Clocks Description
9F LAHF 2 Load: AH = flags SF ZF xx AF xx PF xx CF
Operation
AH  SF:ZF:xx:AF:xx:PF:xx:CF;
Description
LAHF transfers the low byte of the flags word to AH. The bits, from
MSB to LSB, are sign, zero, indeterminate, auxiliary, carry,
indeterminate, parity, indeterminate, and carry.
Flags Affected
None
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
LAR ÄÄ Load Access Rights Byte
Opcode Instruction Clocks Description
0F 02 /r LAR r16,r/m16 pm=15/16 r16  r/m16 masked by FF00
0F 02 /r LAR r32,r/m32 pm=15/16 r32  r/m32 masked by 00FxFF00
Description
The LAR instruction stores a marked form of the second doubleword of
the descriptor for the source selector if the selector is visible at the
CPL (modified by the selector's RPL) and is a valid descriptor type. The
destination register is loaded with the high-order doubleword of the
descriptor masked by 00FxFF00, and ZF is set to 1. The x indicates that the
four bits corresponding to the upper four bits of the limit are undefined in
the value loaded by LAR. If the selector is invisible or of the wrong type,
ZF is cleared.
If the 32-bit operand size is specified, the entire 32-bit value is loaded
into the 32-bit destination register. If the 16-bit operand size is
specified, the lower 16-bits of this value are stored in the 16-bit
destination register.
All code and data segment descriptors are valid for LAR.
The valid special segment and gate descriptor types for LAR are given
in the following table:
Type Name Valid/Invalid
0 Invalid Invalid
1 Available 80286 TSS Valid
2 LDT Valid
3 Busy 80286 TSS Valid
4 80286 call gate Valid
5 80286/80386 task gate Valid
6 80286 trap gate Valid
7 80286 interrupt gate Valid
8 Invalid Invalid
9 Available 80386 TSS Valid
A Invalid Invalid
B Busy 80386 TSS Valid
C 80386 call gate Valid
D Invalid Invalid
E 80386 trap gate Valid
F 80386 interrupt gate Valid
Flags Affected
ZF as described above
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 6; LAR is unrecognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode
LEA ÄÄ Load Effective Address
Opcode Instruction Clocks Description
8D /r LEA r16,m 2 Store effective address for m in register r16
8D /r LEA r32,m 2 Store effective address for m in register r32
8D /r LEA r16,m 2 Store effective address for m in register r16
8D /r LEA r32,m 2 Store effective address for m in register r32
Operation
IF OperandSize = 16 AND AddressSize = 16
THEN r16  Addr(m);
ELSE
IF OperandSize = 16 AND AddressSize = 32
THEN
r16  Truncate_to_16bits(Addr(m)); (* 32-bit address *)
ELSE
IF OperandSize = 32 AND AddressSize = 16
THEN
r32  Truncate_to_16bits(Addr(m));
ELSE
IF OperandSize = 32 AND AddressSize = 32
THEN r32  Addr(m);
FI;
FI;
FI;
FI;
Description
LEA calculates the effective address (offset part) and stores it in the
specified register. The operand-size attribute of the instruction
(represented by OperandSize in the algorithm under "Operation" above) is
determined by the chosen register. The address-size attribute (represented
by AddressSize) is determined by the USE attribute of the segment containing
the second operand. The address-size and operand-size attributes affect the
action performed by LEA, as follows:
Operand Size Address Size Action Performed
16 16 16-bit effective address is calculated and
stored in requested 16-bit register
destination.
16 32 32-bit effective address is calculated. The
lower 16 bits of the address are stored in
the requested 16-bit register destination.
32 16 16-bit effective address is calculated. The
16-bit address is zero-extended and stored
in the requested 32-bit register destination.
32 32 32-bit effective address is calculated and
stored in the requested 32-bit register
destination.
Flags Affected
None
Protected Mode Exceptions
#UD if the second operand is a register
Real Address Mode Exceptions
Interrupt 6 if the second operand is a register
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode
LEAVE ÄÄ High Level Procedure Exit
Opcode Instruction Clocks Description
C9 LEAVE 4 Set SP to BP, then pop BP
C9 LEAVE 4 Set ESP to EBP, then pop EBP
Operation
IF StackAddrSize = 16
THEN
SP  BP;
ELSE (* StackAddrSize = 32 *)
ESP  EBP;
FI;
IF OperandSize = 16
THEN
BP  Pop();
ELSE (* OperandSize = 32 *)
EBP  Pop();
FI;
Description
LEAVE reverses the actions of the ENTER instruction. By copying the
frame pointer to the stack pointer, LEAVE releases the stack space used
by a procedure for its local variables. The old frame pointer is popped
into BP or EBP, restoring the caller's frame. A subsequent RET
instruction removes any arguments pushed onto the stack of the exiting
procedure.
Flags Affected
None
Protected Mode Exceptions
#SS(0) if BP does not point to a location within the limits of the current
stack segment
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode
LGDT/LIDT ÄÄ Load Global/Interrupt Descriptor Table Register
Opcode Instruction Clocks Description
0F 01 /2 LGDT m16&32 11 Load m into GDTR
0F 01 /3 LIDT m16&32 11 Load m into IDTR
Operation
IF instruction = LIDT
THEN
IF OperandSize = 16
THEN IDTR.Limit:Base  m16:24 (* 24 bits of base loaded *)
ELSE IDTR.Limit:Base  m16:32
FI;
ELSE (* instruction = LGDT *)
IF OperandSize = 16
THEN GDTR.Limit:Base  m16:24 (* 24 bits of base loaded *)
ELSE GDTR.Limit:Base  m16:32;
FI;
FI;
Description
The LGDT and LIDT instructions load a linear base address and limit
value from a six-byte data operand in memory into the GDTR or IDTR,
respectively. If a 16-bit operand is used with LGDT or LIDT, the
register is loaded with a 16-bit limit and a 24-bit base, and the
high-order eight bits of the six-byte data operand are not used. If a 32-bit
operand is used, a 16-bit limit and a 32-bit base is loaded; the high-order
eight bits of the six-byte operand are used as high-order base address bits.
The SGDT and SIDT instructions always store into all 48 bits of the
six-byte data operand. With the 80286, the upper eight bits are undefined
after SGDT or SIDT is executed. With the 80386, the upper eight bits
are written with the high-order eight address bits, for both a 16-bit
operand and a 32-bit operand. If LGDT or LIDT is used with a 16-bit
operand to load the register stored by SGDT or SIDT, the upper eight
bits are stored as zeros.
LGDT and LIDT appear in operating system software; they are not used
in application programs. They are the only instructions that directly load
a linear address (i.e., not a segment relative address) in 80386 Protected
Mode.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the current privilege level is not 0; #UD if the source operand
is a register; #GP(0) for an illegal memory operand effective address in
the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in
the SS segment; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH; Interrupt 6 if the source operand is a
register
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Note:
These instructions are valid in Real Address Mode to allow
power-up initialization for Protected Mode
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
LGS/LSS/LDS/LES/LFS ÄÄ Load Full Pointer
Opcode Instruction Clocks Description
C5 /r LDS r16,m16:16 7,p=22 Load DS:r16 with pointer from memory
C5 /r LDS r32,m16:32 7,p=22 Load DS:r32 with pointer from memory
0F B2 /r LSS r16,m16:16 7,p=22 Load SS:r16 with pointer from memory
0F B2 /r LSS r32,m16:32 7,p=22 Load SS:r32 with pointer from memory
C4 /r LES r16,m16:16 7,p=22 Load ES:r16 with pointer from memory
C4 /r LES r32,m16:32 7,p=22 Load ES:r32 with pointer from memory
0F B4 /r LFS r16,m16:16 7,p=25 Load FS:r16 with pointer from memory
0F B4 /r LFS r32,m16:32 7,p=25 Load FS:r32 with pointer from memory
0F B5 /r LGS r16,m16:16 7,p=25 Load GS:r16 with pointer from memory
0F B5 /r LGS r32,m16:32 7,p=25 Load GS:r32 with pointer from memory
Operation
CASE instruction OF
LSS: Sreg is SS; (* Load SS register *)
LDS: Sreg is DS; (* Load DS register *)
LES: Sreg is ES; (* Load ES register *)
LFS: Sreg is FS; (* Load FS register *)
LGS: Sreg is DS; (* Load GS register *)
ESAC;
IF (OperandSize = 16)
THEN
r16  [Effective Address]; (* 16-bit transfer *)
Sreg  [Effective Address + 2]; (* 16-bit transfer *)
(* In Protected Mode, load the descriptor into the segment register *)
ELSE (* OperandSize = 32 *)
r32  [Effective Address]; (* 32-bit transfer *)
Sreg  [Effective Address + 4]; (* 16-bit transfer *)
(* In Protected Mode, load the descriptor into the segment register *)
FI;
Description
These instructions read a full pointer from memory and store it in the
selected segment register:register pair. The full pointer loads 16 bits
into the segment register SS, DS, ES, FS, or GS. The other register loads 32
bits if the operand-size attribute is 32 bits, or loads 16 bits if the
operand-size attribute is 16 bits. The other 16- or 32-bit register to be
loaded is determined by the r16 or r32 register operand specified.
When an assignment is made to one of the segment registers, the
descriptor is also loaded into the segment register. The data for the
register is obtained from the descriptor table entry for the selector
given.
A null selector (values 0000-0003) can be loaded into DS, ES, FS, or
GS registers without causing a protection exception. (Any subsequent
reference to a segment whose corresponding segment register is loaded
with a null selector to address memory causes a #GP(0) exception. No
memory reference to the segment occurs.)
The following is a listing of the Protected Mode checks and actions taken in
the loading of a segment register:
IF SS is loaded:
IF selector is null THEN #GP(0); FI;
Selector index must be within its descriptor table limits ELSE
#GP(selector);
Selector's RPL must equal CPL ELSE #GP(selector);
AR byte must indicate a writable data segment ELSE #GP(selector);
DPL in the AR byte must equal CPL ELSE #GP(selector);
Segment must be marked present ELSE #SS(selector);
Load SS with selector;
Load SS with descriptor;
IF DS, ES, FS, or GS is loaded with non-null selector:
Selector index must be within its descriptor table limits ELSE
#GP(selector);
AR byte must indicate data or readable code segment ELSE
#GP(selector);
IF data or nonconforming code
THEN both the RPL and the CPL must be less than or equal to DPL in
AR byte;
ELSE #GP(selector);
Segment must be marked present ELSE #NP(selector);
Load segment register with selector and RPL bits;
Load segment register with descriptor;
IF DS, ES, FS or GS is loaded with a null selector:
Clear descriptor valid bit;
Flags Affected
None
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
the second operand must be a memory operand, not a register; #GP(0)
if a null selector is loaded into SS; #PF(fault-code) for a page fault
Real Address Mode Exceptions
The second operand must be a memory operand, not a register; Interrupt
13 if any part of the operand would lie outside of the effective address
space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
LLDT ÄÄ Load Local Descriptor Table Register
Opcode Instruction Clocks Description
0F 00 /2 LLDT r/m16 20 Load selector r/m16 into LDTR
Operation
LDTR  SRC;
Description
LLDT loads the Local Descriptor Table register (LDTR). The word
operand (memory or register) to LLDT should contain a selector to the
Global Descriptor Table (GDT). The GDT entry should be a Local Descriptor
Table. If so, then the LDTR is loaded from the entry. The descriptor
registers DS, ES, SS, FS, GS, and CS are not affected. The LDT field in the
task state segment does not change.
The selector operand can be 0; if so, the LDTR is marked invalid. All
descriptor references (except by the LAR, VERR, VERW or LSL
instructions) cause a #GP fault.
LLDT is used in operating system software; it is not used in application
programs.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the current privilege level is not 0; #GP(selector) if the
selector operand does not point into the Global Descriptor Table, or if the
entry in the GDT is not a Local Descriptor Table; #NP(selector) if the
LDT descriptor is not present; #GP(0) for an illegal memory operand
effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an
illegal address in the SS segment; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 6; LLDT is not recognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode (because the instruction is
not recognized, it will not execute or perform a memory reference)
Note
The operand-size attribute has no effect on this instruction.
LMSW ÄÄ Load Machine Status Word
Opcode Instruction Clocks Description
0F 01 /6 LMSW r/m16 10/13 Load r/m16 in machine status word
Operation
MSW  r/m16; (* 16 bits is stored in the machine status word *)
Description
LMSW loads the machine status word (part of CR0) from the source
operand. This instruction can be used to switch to Protected Mode; if so,
it must be followed by an intrasegment jump to flush the instruction
queue. LMSW will not switch back to Real Address Mode.
LMSW is used only in operating system software. It is not used in
application programs.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the current privilege level is not 0; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
Notes
The operand-size attribute has no effect on this instruction. This
instruction is provided for compatibility with the 80286; 80386 programs
should use MOV CR0, ... instead.
LOCK ÄÄ Assert LOCK# Signal Prefix
Opcode Instruction Clocks Description
F0 LOCK 0 Assert LOCK# signal for the next instruction
Description
The LOCK prefix causes the LOCK# signal of the 80386 to be asserted
during execution of the instruction that follows it. In a multiprocessor
environment, this signal can be used to ensure that the 80386 has
exclusive use of any shared memory while LOCK# is asserted. The
read-modify-write sequence typically used to implement test-and-set on the
80386 is the BTS instruction.
The LOCK prefix functions only with the following instructions:
BT, BTS, BTR, BTC mem, reg/imm
XCHG reg, mem
XCHG mem, reg
ADD, OR, ADC, SBB, AND, SUB, XOR mem, reg/imm
NOT, NEG, INC, DEC mem
An undefined opcode trap will be generated if a LOCK prefix is used
with any instruction not listed above.
XCHG always asserts LOCK# regardless of the presence or absence of
the LOCK prefix.
The integrity of the LOCK is not affected by the alignment of the
memory field. Memory locking is observed for arbitrarily misaligned
fields.
Locked access is not assured if another 80386 processor is executing an
instruction concurrently that has one of the following characteristics:
þ Is not preceded by a LOCK prefix
þ Is not one of the instructions in the preceding list
þ Specifies a memory operand that does not exactly overlap the
destination operand. Locking is not guaranteed for partial overlap,
even if one memory operand is wholly contained within another.
Flags Affected
None
Protected Mode Exceptions
#UD if LOCK is used with an instruction not listed in the "Description"
section above; other exceptions can be generated by the subsequent
(locked) instruction
Real Address Mode Exceptions
Interrupt 6 if LOCK is used with an instruction not listed in the
"Description" section above; exceptions can still be generated by the
subsequent (locked) instruction
Virtual 8086 Mode Exceptions
#UD if LOCK is used with an instruction not listed in the "Description"
section above; exceptions can still be generated by the subsequent (locked)
instruction
LODS/LODSB/LODSW/LODSD ÄÄ Load String Operand
Opcode Instruction Clocks Description
AC LODS m8 5 Load byte [(E)SI] into AL
AD LODS m16 5 Load word [(E)SI] into AX
AD LODS m32 5 Load dword [(E)SI] into EAX
AC LODSB 5 Load byte DS:[(E)SI] into AL
AD LODSW 5 Load word DS:[(E)SI] into AX
AD LODSD 5 Load dword DS:[(E)SI] into EAX
Operation
IF AddressSize = 16
THEN use SI for source-index
ELSE (* AddressSize = 32 *)
use ESI for source-index;
FI;
IF byte type of instruction
THEN
AL  [source-index]; (* byte load *)
IF DF = 0 THEN IncDec  1 ELSE IncDec  -1; FI;
ELSE
IF OperandSize = 16
THEN
AX  [source-index]; (* word load *)
IF DF = 0 THEN IncDec  2 ELSE IncDec  -2; FI;
ELSE (* OperandSize = 32 *)
EAX  [source-index]; (* dword load *)
IF DF = 0 THEN IncDec  4 ELSE IncDec  -4; FI;
FI;
FI;
source-index  source-index + IncDec
Description
LODS loads the AL, AX, or EAX register with the memory byte, word,
or doubleword at the location pointed to by the source-index register.
After the transfer is made, the source-index register is automatically
advanced. If the direction flag is 0 (CLD was executed), the source index
increments; if the direction flag is 1 (STD was executed), it decrements.
The increment or decrement is 1 if a byte is loaded, 2 if a word is loaded,
or 4 if a doubleword is loaded.
If the address-size attribute for this instruction is 16 bits, SI is used
for the source-index register; otherwise the address-size attribute is 32
bits, and the ESI register is used. The address of the source data is
determined solely by the contents of ESI/SI. Load the correct index value
into SI before executing the LODS instruction. LODSB, LODSW, LODSD are
synonyms for the byte, word, and doubleword LODS instructions.
LODS can be preceded by the REP prefix; however, LODS is used more typically
within a LOOP construct, because further processing of the data moved into
EAX, AX, or AL is usually necessary.
Flags Affected
None
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
LOOP/LOOPcond ÄÄ Loop Control with CX Counter
Opcode Instruction Clocks Description
E2 cb LOOP rel8 11+m DEC count; jump short if count <> 0
E1 cb LOOPE rel8 11+m DEC count; jump short if count <> 0 and ZF=1
E1 cb LOOPZ rel8 11+m DEC count; jump short if count <> 0 and ZF=1
E0 cb LOOPNE rel8 11+m DEC count; jump short if count <> 0 and ZF=0
E0 cb LOOPNZ rel8 11+m DEC count; jump short if count <> 0 and ZF=0
Operation
IF AddressSize = 16 THEN CountReg is CX ELSE CountReg is ECX; FI;
CountReg  CountReg - 1;
IF instruction <> LOOP
THEN
IF (instruction = LOOPE) OR (instruction = LOOPZ)
THEN BranchCond  (ZF = 1) AND (CountReg <> 0);
FI;
IF (instruction = LOOPNE) OR (instruction = LOOPNZ)
THEN BranchCond  (ZF = 0) AND (CountReg <> 0);
FI;
FI;
IF BranchCond
THEN
IF OperandSize = 16
THEN
IP  IP + SignExtend(rel8);
ELSE (* OperandSize = 32 *)
EIP  EIP + SignExtend(rel8);
FI;
FI;
Description
LOOP decrements the count register without changing any of the flags.
Conditions are then checked for the form of LOOP being used. If the
conditions are met, a short jump is made to the label given by the operand
to LOOP. If the address-size attribute is 16 bits, the CX register is used
as the count register; otherwise the ECX register is used. The operand
of LOOP must be in the range from 128 (decimal) bytes before the
instruction to 127 bytes ahead of the instruction.
The LOOP instructions provide iteration control and combine loop index
management with conditional branching. Use the LOOP instruction by
loading an unsigned iteration count into the count register, then code the
LOOP at the end of a series of instructions to be iterated. The
destination of LOOP is a label that points to the beginning of the
iteration.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the offset jumped to is beyond the limits of the current code
segment
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
LSL ÄÄ Load Segment Limit
Opcode Instruction Clocks Description
0F 03 /r LSL r16,r/m16 pm=20/21 Load: r16  segment limit,
selector r/m16 (byte granular)
0F 03 /r LSL r32,r/m32 pm=20/21 Load: r32  segment limit,
selector r/m32 (byte granular)
0F 03 /r LSL r16,r/m16 pm=25/26 Load: r16  segment limit,
selector r/m16 (page granular)
0F 03 /r LSL r32,r/m32 pm=25/26 Load: r32  segment limit,
selector r/m32 (page granular)
Description
The LSL instruction loads a register with an unscrambled segment limit,
and sets ZF to 1, provided that the source selector is visible at the CPL
weakened by RPL, and that the descriptor is a type accepted by LSL.
Otherwise, ZF is cleared to 0, and the destination register is unchanged.
The segment limit is loaded as a byte granular value. If the descriptor
has a page granular segment limit, LSL will translate it to a byte limit
before loading it in the destination register (shift left 12 the 20-bit
"raw" limit from descriptor, then OR with 00000FFFH).
The 32-bit forms of this instruction store the 32-bit byte granular limit
in the 16-bit destination register.
Code and data segment descriptors are valid for LSL.
The valid special segment and gate descriptor types for LSL are given
in the following table:
Type Name Valid/Invalid
0 Invalid Invalid
1 Available 80286 TSS Valid
2 LDT Valid
3 Busy 80286 TSS Valid
4 80286 call gate Invalid
5 80286/80386 task gate Invalid
6 80286 trap gate Invalid
7 80286 interrupt gate Invalid
8 Invalid Valid
9 Available 80386 TSS Valid
A Invalid Invalid
B Busy 80386 TSS Valid
C 80386 call gate Invalid
D Invalid Invalid
E 80386 trap gate Invalid
F 80386 interrupt gate Invalid
Flags Affected
ZF as described above
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 6; LSL is not recognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode
LTR ÄÄ Load Task Register
Opcode Instruction Clocks Description
0F 00 /3 LTR r/m16 pm=23/27 Load EA word into task register
Description
LTR loads the task register from the source register or memory location
specified by the operand. The loaded task state segment is marked busy.
A task switch does not occur.
LTR is used only in operating system software; it is not used in
application programs.
Flags Affected
None
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#GP(0) if the current privilege level is not 0; #GP(selector) if the object
named by the source selector is not a TSS or is already busy;
#NP(selector) if the TSS is marked "not present"; #PF(fault-code) for
a page fault
Real Address Mode Exceptions
Interrupt 6; LTR is not recognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode
Notes
The operand-size attribute has no effect on this instruction.
MOV ÄÄ Move Data
Opcode Instruction Clocks Description
88 /r MOV r/m8,r8 2/2 Move byte register to r/m byte
89 /r MOV r/m16,r16 2/2 Move word register to r/m word
89 /r MOV r/m32,r32 2/2 Move dword register to r/m dword
8A /r MOV r8,r/m8 2/4 Move r/m byte to byte register
8B /r MOV r16,r/m16 2/4 Move r/m word to word register
8B /r MOV r32,r/m32 2/4 Move r/m dword to dword register
8C /r MOV r/m16,Sreg 2/2 Move segment register to r/m word
8D /r MOV Sreg,r/m16 2/5,pm=18/19 Move r/m word to segment register
A0 MOV AL,moffs8 4 Move byte at (seg:offset) to AL
A1 MOV AX,moffs16 4 Move word at (seg:offset) to AX
A1 MOV EAX,moffs32 4 Move dword at (seg:offset) to EAX
A2 MOV moffs8,AL 2 Move AL to (seg:offset)
A3 MOV moffs16,AX 2 Move AX to (seg:offset)
A3 MOV moffs32,EAX 2 Move EAX to (seg:offset)
B0 + rb MOV reg8,imm8 2 Move immediate byte to register
B8 + rw MOV reg16,imm16 2 Move immediate word to register
B8 + rd MOV reg32,imm32 2 Move immediate dword to register
C6 MOV r/m8,imm8 2/2 Move immediate byte to r/m byte
C7 MOV r/m16,imm16 2/2 Move immediate word to r/m word
C7 MOV r/m32,imm32 2/2 Move immediate dword to r/m dword
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
moffs8, moffs16, and moffs32 all consist of a simple offset relative
to the segment base. The 8, 16, and 32 refer to the size of the data. The
address-size attribute of the instruction determines the size of the
offset, either 16 or 32 bits.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
DEST  SRC;
Description
MOV copies the second operand to the first operand.
If the destination operand is a segment register (DS, ES, SS, etc.), then
data from a descriptor is also loaded into the register. The data for the
register is obtained from the descriptor table entry for the selector
given. A null selector (values 0000-0003) can be loaded into DS and ES
registers without causing an exception; however, use of DS or ES causes a
#GP(0), and no memory reference occurs.
A MOV into SS inhibits all interrupts until after the execution of the
next instruction (which is presumably a MOV into eSP).
Loading a segment register under 80386 Protected Mode results in special
checks and actions, as described in the following listing:
IF SS is loaded;
THEN
IF selector is null THEN #GP(0);
FI;
Selector index must be within its descriptor table limits else
#GP(selector);
Selector's RPL must equal CPL else #GP(selector);
AR byte must indicate a writable data segment else #GP(selector);
DPL in the AR byte must equal CPL else #GP(selector);
Segment must be marked present else #SS(selector);
Load SS with selector;
Load SS with descriptor.
FI;
IF DS, ES, FS or GS is loaded with non-null selector;
THEN
Selector index must be within its descriptor table limits
else #GP(selector);
AR byte must indicate data or readable code segment else
#GP(selector);
IF data or nonconforming code segment
THEN both the RPL and the CPL must be less than or equal to DPL in
AR byte;
ELSE #GP(selector);
FI;
Segment must be marked present else #NP(selector);
Load segment register with selector;
Load segment register with descriptor;
FI;
IF DS, ES, FS or GS is loaded with a null selector;
THEN
Load segment register with selector;
Clear descriptor valid bit;
FI;
Flags Affected
None
Protected Mode Exceptions
#GP, #SS, and #NP if a segment register is being loaded; otherwise,
#GP(0) if the destination is in a nonwritable segment; #GP(0) for an
illegal memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
MOV ÄÄ Move to/from Special Registers
Opcode Instruction Clocks Description
0F 20 /r MOV r32,CR0/CR2/CR3 6 Move (control register) to
(register)
0F 22 /r MOV CR0/CR2/CR3,r32 10/4/5 Move (register) to (control
register)
0F 21 /r MOV r32,DR0 -- 3 22 Move (debug register) to
(register)
0F 21 /r MOV r32,DR6/DR7 14 Move (debug register) to
(register)
0F 23 /r MOV DR0 -- 3,r32 22 Move (register) to (debug
register)
0F 23 /r MOV DR6/DR7,r32 16 Move (register) to (debug
register)
0F 24 /r MOV r32,TR6/TR7 12 Move (test register) to
(register)
0F 26 /r MOV TR6/TR7,r32 12 Move (register) to (test
register)
Operation
DEST  SRC;
Description
The above forms of MOV store or load the following special registers in
or from a general purpose register:
þ Control registers CR0, CR2, and CR3
þ Debug Registers DR0, DR1, DR2, DR3, DR6, and DR7
þ Test Registers TR6 and TR7
32-bit operands are always used with these instructions, regardless of the
operand-size attribute.
Flags Affected
OF, SF, ZF, AF, PF, and CF are undefined
Protected Mode Exceptions
#GP(0) if the current privilege level is not 0
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
#GP(0) if instruction execution is attempted
Notes
The instructions must be executed at privilege level 0 or in real-address
mode; otherwise, a protection exception will be raised.
The reg field within the ModRM byte specifies which of the special
registers in each category is involved. The two bits in the field are
always 11. The r/m field specifies the general register involved.
MOVS/MOVSB/MOVSW/MOVSD ÄÄ Move Data from String to String
Opcode Instruction Clocks Description
A4 MOVS m8,m8 7 Move byte [(E)SI] to ES:[(E)DI]
A5 MOVS m16,m16 7 Move word [(E)SI] to ES:[(E)DI]
A5 MOVS m32,m32 7 Move dword [(E)SI] to ES:[(E)DI]
A4 MOVSB 7 Move byte DS:[(E)SI] to ES:[(E)DI]
A5 MOVSW 7 Move word DS:[(E)SI] to ES:[(E)DI]
A5 MOVSD 7 Move dword DS:[(E)SI] to ES:[(E)DI]
Operation
IF (instruction = MOVSD) OR (instruction has doubleword operands)
THEN OperandSize  32;
ELSE OperandSize  16;
IF AddressSize = 16
THEN use SI for source-index and DI for destination-index;
ELSE (* AddressSize = 32 *)
use ESI for source-index and EDI for destination-index;
FI;
IF byte type of instruction
THEN
[destination-index]  [source-index]; (* byte assignment *)
IF DF = 0 THEN IncDec  1 ELSE IncDec  -1; FI;
ELSE
IF OperandSize = 16
THEN
[destination-index]  [source-index]; (* word assignment *)
IF DF = 0 THEN IncDec  2 ELSE IncDec  -2; FI;
ELSE (* OperandSize = 32 *)
[destination-index]  [source-index]; (* doubleword assignment *)
IF DF = 0 THEN IncDec  4 ELSE IncDec  -4; FI;
FI;
FI;
source-index  source-index + IncDec;
destination-index  destination-index + IncDec;
Description
MOVS copies the byte or word at [(E)SI] to the byte or word at
ES:[(E)DI]. The destination operand must be addressable from the ES
register; no segment override is possible for the destination. A segment
override can be used for the source operand; the default is DS.
The addresses of the source and destination are determined solely by the
contents of (E)SI and (E)DI. Load the correct index values into (E)SI
and (E)DI before executing the MOVS instruction. MOVSB, MOVSW,
and MOVSD are synonyms for the byte, word, and doubleword MOVS
instructions.
After the data is moved, both (E)SI and (E)DI are advanced
automatically. If the direction flag is 0 (CLD was executed), the registers
are incremented; if the direction flag is 1 (STD was executed), the
registers are decremented. The registers are incremented or decremented by 1
if a byte was moved, 2 if a word was moved, or 4 if a doubleword was moved.
MOVS can be preceded by the REP prefix for block movement of CX
bytes or words. Refer to the REP instruction for details of this operation.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
MOVSX ÄÄ Move with Sign-Extend
Opcode Instruction Clocks Description
0F BE /r MOVSX r16,r/m8 3/6 Move byte to word with sign-extend
0F BE /r MOVSX r32,r/m8 3/6 Move byte to dword, sign-extend
0F BF /r MOVSX r32,r/m16 3/6 Move word to dword, sign-extend
Operation
DEST  SignExtend(SRC);
Description
MOVSX reads the contents of the effective address or register as a byte
or a word, sign-extends the value to the operand-size attribute of the
instruction (16 or 32 bits), and stores the result in the destination
register.
Flags Affected
None
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
MOVZX ÄÄ Move with Zero-Extend
Opcode Instruction Clocks Description
0F B6 /r MOVZX r16,r/m8 3/6 Move byte to word with zero-extend
0F B6 /r MOVZX r32,r/m8 3/6 Move byte to dword, zero-extend
0F B7 /r MOVZX r32,r/m16 3/6 Move word to dword, zero-extend
Operation
DEST  ZeroExtend(SRC);
Description
MOVZX reads the contents of the effective address or register as a byte
or a word, zero extends the value to the operand-size attribute of the
instruction (16 or 32 bits), and stores the result in the destination
register.
Flags Affected
None
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
MUL ÄÄ Unsigned Multiplication of AL or AX
Opcode Instruction Clocks Description
F6 /4 MUL AL,r/m8 9-14/12-17 Unsigned multiply (AX  AL * r/m byte)
F7 /4 MUL AX,r/m16 9-22/12-25 Unsigned multiply (DX:AX  AX * r/m
word)
F7 /4 MUL EAX,r/m32 9-38/12-41 Unsigned multiply (EDX:EAX  EAX * r/m
dword)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
The 80386 uses an early-out multiply algorithm. The actual number of
clocks depends on the position of the most significant bit in the
optimizing multiplier, shown underlined above. The optimization occurs
for positive and negative multiplier values. Because of the early-out
algorithm, clock counts given are minimum to maximum. To calculate the
actual clocks, use the following formula:
Actual clock = if <> 0 then max(ceiling(log{2} ³m³), 3) + 6 clocks;
Actual clock = if = 0 then 9 clocks
where m is the multiplier.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
IF byte-size operation
THEN AX  AL * r/m8
ELSE (* word or doubleword operation *)
IF OperandSize = 16
THEN DX:AX  AX * r/m16
ELSE (* OperandSize = 32 *)
EDX:EAX  EAX * r/m32
FI;
FI;
Description
MUL performs unsigned multiplication. Its actions depend on the size
of its operand, as follows:
þ A byte operand is multiplied by AL; the result is left in AX. The
carry and overflow flags are set to 0 if AH is 0; otherwise, they are
set to 1.
þ A word operand is multiplied by AX; the result is left in DX:AX.
DX contains the high-order 16 bits of the product. The carry and
overflow flags are set to 0 if DX is 0; otherwise, they are set to 1.
þ A doubleword operand is multiplied by EAX and the result is left in
EDX:EAX. EDX contains the high-order 32 bits of the product. The
carry and overflow flags are set to 0 if EDX is 0; otherwise, they are
set to 1.
Flags Affected
OF and CF as described above; SF, ZF, AF, PF, and CF are undefined
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
NEG ÄÄ Two's Complement Negation
Opcode Instruction Clocks Description
F6 /3 NEG r/m8 2/6 Two's complement negate r/m byte
F7 /3 NEG r/m16 2/6 Two's complement negate r/m word
F7 /3 NEG r/m32 2/6 Two's complement negate r/m dword
Operation
IF r/m = 0 THEN CF  0 ELSE CF  1; FI;
r/m  - r/m;
Description
NEG replaces the value of a register or memory operand with its two's
complement. The operand is subtracted from zero, and the result is placed
in the operand.
The carry flag is set to 1, unless the operand is zero, in which case the
carry flag is cleared to 0.
Flags Affected
CF as described above; OF, SF, ZF, and PF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page
fault
NOP ÄÄ No Operation
Opcode Instruction Clocks Description
90 NOP 3 No operation
Description
NOP performs no operation. NOP is a one-byte instruction that takes
up space but affects none of the machine context except (E)IP.
NOP is an alias mnemonic for the XCHG (E)AX, (E)AX instruction.
Flags Affected
None
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
NOT ÄÄ One's Complement Negation
Opcode Instruction Clocks Description
F6 /2 NOT r/m8 2/6 Reverse each bit of r/m byte
F7 /2 NOT r/m16 2/6 Reverse each bit of r/m word
F7 /2 NOT r/m32 2/6 Reverse each bit of r/m dword
Operation
r/m  NOT r/m;
Description
NOT inverts the operand; every 1 becomes a 0, and vice versa.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page
fault
OR ÄÄ Logical Inclusive OR
Opcode Instruction Clocks Description
0C ib OR AL,imm8 2 OR immediate byte to AL
0D iw OR AX,imm16 2 OR immediate word to AX
0D id OR EAX,imm32 2 OR immediate dword to EAX
80 /1 ib OR r/m8,imm8 2/7 OR immediate byte to r/m byte
81 /1 iw OR r/m16,imm16 2/7 OR immediate word to r/m word
81 /1 id OR r/m32,imm32 2/7 OR immediate dword to r/m dword
83 /1 ib OR r/m16,imm8 2/7 OR sign-extended immediate byte
with r/m word
83 /1 ib OR r/m32,imm8 2/7 OR sign-extended immediate byte
with r/m dword
08 /r OR r/m8,r8 2/6 OR byte register to r/m byte
09 /r OR r/m16,r16 2/6 OR word register to r/m word
09 /r OR r/m32,r32 2/6 OR dword register to r/m dword
0A /r OR r8,r/m8 2/7 OR byte register to r/m byte
0B /r OR r16,r/m16 2/7 OR word register to r/m word
0B /r OR r32,r/m32 2/7 OR dword register to r/m dword
Operation
DEST  DEST OR SRC;
CF  0;
OF  0
Description
OR computes the inclusive OR of its two operands and places the result
in the first operand. Each bit of the result is 0 if both corresponding
bits of the operands are 0; otherwise, each bit is 1.
Flags Affected
OF  0, CF  0; SF, ZF, and PF as described in Appendix C; AF is
undefined
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page
fault
OUT ÄÄ Output to Port
Opcode Instruction Clocks Description
E6 ib OUT imm8,AL 10,pm=4*/24** Output byte AL to immediate port
number
E7 ib OUT imm8,AX 10,pm=4*/24** Output word AL to immediate port
number
E7 ib OUT imm8,EAX 10,pm=4*/24** Output dword AL to immediate
port number
EE OUT DX,AL 11,pm=5*/25** Output byte AL to port number in
DX
EF OUT DX,AX 11,pm=5*/25** Output word AL to port number in
DX
EF OUT DX,EAX 11,pm=5*/25** Output dword AL to port number
in DX
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
*If CPL ó IOPL
**If CPL > IOPL or if in virtual 8086 mode
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
IF NOT I-O-Permission (DEST, width(DEST))
THEN #GP(0);
FI;
FI;
[DEST]  SRC; (* I/O address space used *)
Description
OUT transfers a data byte or data word from the register (AL, AX, or
EAX) given as the second operand to the output port numbered by the
first operand. Output to any port from 0 to 65535 is performed by placing
the port number in the DX register and then using an OUT instruction
with DX as the first operand. If the instruction contains an eight-bit port
ID, that value is zero-extended to 16 bits.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the current privilege level is higher (has less privilege) than
IOPL and any of the corresponding I/O permission bits in TSS equals 1
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
#GP(0) fault if any of the corresponding I/O permission bits in TSS
equals 1
OUTS/OUTSB/OUTSW/OUTSD ÄÄ Output String to Port
Opcode Instruction Clocks Description
6E OUTS DX,r/m8 14,pm=8*/28** Output byte [(E)SI] to port in DX
6F OUTS DX,r/m16 14,pm=8*/28** Output word [(E)SI] to port in DX
6F OUTS DX,r/m32 14,pm=8*/28** Output dword [(E)SI] to port in DX
6E OUTSB 14,pm=8*/28** Output byte DS:[(E)SI] to port in
DX
6F OUTSW 14,pm=8*/28** Output word DS:[(E)SI] to port in
DX
6F OUTSD 14,pm=8*/28** Output dword DS:[(E)SI] to port in
DX
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
NOTES:
*If CPL ó IOPL
**If CPL > IOPL or if in virtual 8086 mode
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Operation
IF AddressSize = 16
THEN use SI for source-index;
ELSE (* AddressSize = 32 *)
use ESI for source-index;
FI;
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
IF NOT I-O-Permission (DEST, width(DEST))
THEN #GP(0);
FI;
FI;
IF byte type of instruction
THEN
[DX]  [source-index]; (* Write byte at DX I/O address *)
IF DF = 0 THEN IncDec  1 ELSE IncDec  -1; FI;
FI;
IF OperandSize = 16
THEN
[DX]  [source-index]; (* Write word at DX I/O address *)
IF DF = 0 THEN IncDec  2 ELSE IncDec  -2; FI;
FI;
IF OperandSize = 32
THEN
[DX]  [source-index]; (* Write dword at DX I/O address *)
IF DF = 0 THEN IncDec  4 ELSE IncDec  -4; FI;
FI;
FI;
source-index  source-index + IncDec;
Description
OUTS transfers data from the memory byte, word, or doubleword at the
source-index register to the output port addressed by the DX register. If
the address-size attribute for this instruction is 16 bits, SI is used for
the source-index register; otherwise, the address-size attribute is 32 bits,
and ESI is used for the source-index register.
OUTS does not allow specification of the port number as an immediate value.
The port must be addressed through the DX register value. Load the correct
value into DX before executing the OUTS instruction.
The address of the source data is determined by the contents of
source-index register. Load the correct index value into SI or ESI before
executing the OUTS instruction.
After the transfer, source-index register is advanced automatically. If
the direction flag is 0 (CLD was executed), the source-index register is
incremented; if the direction flag is 1 (STD was executed), it is
decremented. The amount of the increment or decrement is 1 if a byte is
output, 2 if a word is output, or 4 if a doubleword is output.
OUTSB, OUTSW, and OUTSD are synonyms for the byte, word, and
doubleword OUTS instructions. OUTS can be preceded by the REP
prefix for block output of CX bytes or words. Refer to the REP
instruction for details on this operation.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if CPL is greater than IOPL and any of the corresponding I/O
permission bits in TSS equals 1; #GP(0) for an illegal memory operand
effective address in the CS, DS, or ES segments; #SS(0) for an illegal
address in the SS segment; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
#GP(0) fault if any of the corresponding I/O permission bits in TSS
equals 1; #PF(fault-code) for a page fault
POP ÄÄ Pop a Word from the Stack
Opcode Instruction Clocks Description
8F /0 POP m16 5 Pop top of stack into memory word
8F /0 POP m32 5 Pop top of stack into memory dword
58 + rw POP r16 4 Pop top of stack into word register
58 + rd POP r32 4 Pop top of stack into dword register
1F POP DS 7,pm=21 Pop top of stack into DS
07 POP ES 7,pm=21 Pop top of stack into ES
17 POP SS 7,pm=21 Pop top of stack into SS
0F A1 POP FS 7,pm=21 Pop top of stack into FS
0F A9 POP GS 7,pm=21 Pop top of stack into GS
Operation
IF StackAddrSize = 16
THEN
IF OperandSize = 16
THEN
DEST  (SS:SP); (* copy a word *)
SP  SP + 2;
ELSE (* OperandSize = 32 *)
DEST  (SS:SP); (* copy a dword *)
SP  SP + 4;
FI;
ELSE (* StackAddrSize = 32 * )
IF OperandSize = 16
THEN
DEST  (SS:ESP); (* copy a word *)
ESP  ESP + 2;
ELSE (* OperandSize = 32 *)
DEST  (SS:ESP); (* copy a dword *)
ESP  ESP + 4;
FI;
FI;
Description
POP replaces the previous contents of the memory, the register, or the
segment register operand with the word on the top of the 80386 stack,
addressed by SS:SP (address-size attribute of 16 bits) or SS:ESP
(addresssize attribute of 32 bits). The stack pointer SP is incremented
by 2 for an operand-size of 16 bits or by 4 for an operand-size of 32 bits.
It then points to the new top of stack.
POP CS is not an 80386 instruction. Popping from the stack into the CS
register is accomplished with a RET instruction.
If the destination operand is a segment register (DS, ES, FS, GS, or
SS), the value popped must be a selector. In protected mode, loading the
selector initiates automatic loading of the descriptor information
associated with that selector into the hidden part of the segment register;
loading also initiates validation of both the selector and the descriptor
information.
A null value (0000-0003) may be popped into the DS, ES, FS, or GS
register without causing a protection exception. An attempt to reference
a segment whose corresponding segment register is loaded with a null
value causes a #GP(0) exception. No memory reference occurs. The saved
value of the segment register is null.
A POP SS instruction inhibits all interrupts, including NMI, until after
execution of the next instruction. This allows sequential execution of POP
SS and POP eSP instructions without danger of having an invalid stack
during an interrupt. However, use of the LSS instruction is the preferred
method of loading the SS and eSP registers.
Loading a segment register while in protected mode results in special
checks and actions, as described in the following listing:
IF SS is loaded:
IF selector is null THEN #GP(0);
Selector index must be within its descriptor table limits ELSE
#GP(selector);
Selector's RPL must equal CPL ELSE #GP(selector);
AR byte must indicate a writable data segment ELSE #GP(selector);
DPL in the AR byte must equal CPL ELSE #GP(selector);
Segment must be marked present ELSE #SS(selector);
Load SS register with selector;
Load SS register with descriptor;
IF DS, ES, FS or GS is loaded with non-null selector:
AR byte must indicate data or readable code segment ELSE
#GP(selector);
IF data or nonconforming code
THEN both the RPL and the CPL must be less than or equal to DPL in
AR byte
ELSE #GP(selector);
FI;
Segment must be marked present ELSE #NP(selector);
Load segment register with selector;
Load segment register with descriptor;
IF DS, ES, FS, or GS is loaded with a null selector:
Load segment register with selector
Clear valid bit in invisible portion of register
Flags Affected
None
Protected Mode Exceptions
#GP, #SS, and #NP if a segment register is being loaded; #SS(0) if the
current top of stack is not within the stack segment; #GP(0) if the result
is in a nonwritable segment; #GP(0) for an illegal memory operand
effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an
illegal address in the SS segment; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page
fault
POPA/POPAD ÄÄ Pop all General Registers
Opcode Instruction Clocks Description
61 POPA 24 Pop DI, SI, BP, SP, BX, DX, CX, and AX
61 POPAD 24 Pop EDI, ESI, EBP, ESP, EDX, ECX, and EAX
Operation
IF OperandSize = 16 (* instruction = POPA *)
THEN
DI  Pop();
SI  Pop();
BP  Pop();
throwaway  Pop (); (* Skip SP *)
BX  Pop();
DX  Pop();
CX  Pop();
AX  Pop();
ELSE (* OperandSize = 32, instruction = POPAD *)
EDI  Pop();
ESI  Pop();
EBP  Pop();
throwaway  Pop (); (* Skip ESP *)
EBX  Pop();
EDX  Pop();
ECX  Pop();
EAX  Pop();
FI;
Description
POPA pops the eight 16-bit general registers. However, the SP value is
discarded instead of loaded into SP. POPA reverses a previous PUSHA,
restoring the general registers to their values before PUSHA was
executed. The first register popped is DI.
POPAD pops the eight 32-bit general registers. The ESP value is
discarded instead of loaded into ESP. POPAD reverses the previous
PUSHAD, restoring the general registers to their values before PUSHAD
was executed. The first register popped is EDI.
Flags Affected
None
Protected Mode Exceptions
#SS(0) if the starting or ending stack address is not within the stack
segment; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page
fault
POPF/POPFD ÄÄ Pop Stack into FLAGS or EFLAGS Register
Opcode Instruction Clocks Description
9D POPF 5 Pop top of stack FLAGS
9D POPFD 5 Pop top of stack into EFLAGS
Operation
Flags  Pop();
Description
POPF/POPFD pops the word or doubleword on the top of the stack and
stores the value in the flags register. If the operand-size attribute of
the instruction is 16 bits, then a word is popped and the value is stored in
FLAGS. If the operand-size attribute is 32 bits, then a doubleword is popped
and the value is stored in EFLAGS.
Refer to Chapter 2 and Chapter 4 for information about the FLAGS
and EFLAGS registers. Note that bits 16 and 17 of EFLAGS, called
VM and RF, respectively, are not affected by POPF or POPFD.
The I/O privilege level is altered only when executing at privilege level
0. The interrupt flag is altered only when executing at a level at least as
privileged as the I/O privilege level. (Real-address mode is equivalent to
privilege level 0.) If a POPF instruction is executed with insufficient
privilege, an exception does not occur, but the privileged bits do not
change.
Flags Affected
All flags except VM and RF
Protected Mode Exceptions
#SS(0) if the top of stack is not within the stack segment
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
#GP(0) fault if IOPL is less than 3, to permit emulation
PUSH ÄÄ Push Operand onto the Stack
Opcode Instruction Clocks Description
FF /6 PUSH m16 5 Push memory word
FF /6 PUSH m32 5 Push memory dword
50 + /r PUSH r16 2 Push register word
50 + /r PUSH r32 2 Push register dword
6A PUSH imm8 2 Push immediate byte
68 PUSH imm16 2 Push immediate word
68 PUSH imm32 2 Push immediate dword
0E PUSH CS 2 Push CS
16 PUSH SS 2 Push SS
1E PUSH DS 2 Push DS
06 PUSH ES 2 Push ES
0F A0 PUSH FS 2 Push FS
OF A8 PUSH GS 2 Push GS
Operation
IF StackAddrSize = 16
THEN
IF OperandSize = 16 THEN
SP  SP - 2;
(SS:SP)  (SOURCE); (* word assignment *)
ELSE
SP  SP - 4;
(SS:SP)  (SOURCE); (* dword assignment *)
FI;
ELSE (* StackAddrSize = 32 *)
IF OperandSize = 16
THEN
ESP  ESP - 2;
(SS:ESP)  (SOURCE); (* word assignment *)
ELSE
ESP  ESP - 4;
(SS:ESP)  (SOURCE); (* dword assignment *)
FI;
FI;
Description
PUSH decrements the stack pointer by 2 if the operand-size attribute of
the instruction is 16 bits; otherwise, it decrements the stack pointer by
4. PUSH then places the operand on the new top of stack, which is
pointed to by the stack pointer.
The 80386 PUSH eSP instruction pushes the value of eSP as it existed
before the instruction. This differs from the 8086, where PUSH SP
pushes the new value (decremented by 2).
Flags Affected
None
Protected Mode Exceptions
#SS(0) if the new value of SP or ESP is outside the stack segment limit;
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
None; if SP or ESP is 1, the 80386 shuts down due to a lack of stack
space
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page
fault
PUSHA/PUSHAD ÄÄ Push all General Registers
Opcode Instruction Clocks Description
60 PUSHA 18 Push AX, CX, DX, BX, original SP, BP, SI, and
DI
60 PUSHAD 18 Push EAX, ECX, EDX, EBX, original ESP, EBP,
ESI, and EDI
Operation
IF OperandSize = 16 (* PUSHA instruction *)
THEN
Temp  (SP);
Push(AX);
Push(CX);
Push(DX);
Push(BX);
Push(Temp);
Push(BP);
Push(SI);
Push(DI);
ELSE (* OperandSize = 32, PUSHAD instruction *)
Temp  (ESP);
Push(EAX);
Push(ECX);
Push(EDX);
Push(EBX);
Push(Temp);
Push(EBP);
Push(ESI);
Push(EDI);
FI;
Description
PUSHA and PUSHAD save the 16-bit or 32-bit general registers,
respectively, on the 80386 stack. PUSHA decrements the stack pointer
(SP) by 16 to hold the eight word values. PUSHAD decrements the
stack pointer (ESP) by 32 to hold the eight doubleword values. Because
the registers are pushed onto the stack in the order in which they were
given, they appear in the 16 or 32 new stack bytes in reverse order. The
last register pushed is DI or EDI.
Flags Affected
None
Protected Mode Exceptions
#SS(0) if the starting or ending stack address is outside the stack segment
limit; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Before executing PUSHA or PUSHAD, the 80386 shuts down if SP or
ESP equals 1, 3, or 5; if SP or ESP equals 7, 9, 11, 13, or 15, exception
13 occurs
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page
fault
PUSHF/PUSHFD ÄÄ Push Flags Register onto the Stack
Opcode Instruction Clocks Description
9C PUSHF 4 Push FLAGS
9C PUSHFD 4 Push EFLAGS
Operation
IF OperandSize = 32
THEN push(EFLAGS);
ELSE push(FLAGS);
FI;
Description
PUSHF decrements the stack pointer by 2 and copies the FLAGS
register to the new top of stack; PUSHFD decrements the stack pointer by
4, and the 80386 EFLAGS register is copied to the new top of stack
which is pointed to by SS:eSP. Refer to Chapter 2 and Chapter 4 for
information on the EFLAGS register.
Flags Affected
None
Protected Mode Exceptions
#SS(0) if the new value of eSP is outside the stack segment boundaries
Real Address Mode Exceptions
None; the 80386 shuts down due to a lack of stack space
Virtual 8086 Mode Exceptions
#GP(0) fault if IOPL is less than 3, to permit emulation
RCL/RCR/ROL/ROR ÄÄ Rotate
Opcode Instruction Clocks Description
D0 /2 RCL r/m8,1 9/10 Rotate 9 bits (CF,r/m byte) left
once
D2 /2 RCL r/m8,CL 9/10 Rotate 9 bits (CF,r/m byte) left CL
times
C0 /2 ib RCL r/m8,imm8 9/10 Rotate 9 bits (CF,r/m byte) left
imm8 times
D1 /2 RCL r/m16,1 9/10 Rotate 17 bits (CF,r/m word) left
once
D3 /2 RCL r/m16,CL 9/10 Rotate 17 bits (CF,r/m word) left
CL times
C1 /2 ib RCL r/m16,imm8 9/10 Rotate 17 bits (CF,r/m word) left
imm8 times
D1 /2 RCL r/m32,1 9/10 Rotate 33 bits (CF,r/m dword) left
once
D3 /2 RCL r/m32,CL 9/10 Rotate 33 bits (CF,r/m dword) left
CL times
C1 /2 ib RCL r/m32,imm8 9/10 Rotate 33 bits (CF,r/m dword) left
imm8 times
D0 /3 RCR r/m8,1 9/10 Rotate 9 bits (CF,r/m byte) right
once
D2 /3 RCR r/m8,CL 9/10 Rotate 9 bits (CF,r/m byte) right
CL times
C0 /3 ib RCR r/m8,imm8 9/10 Rotate 9 bits (CF,r/m byte) right
imm8 times
D1 /3 RCR r/m16,1 9/10 Rotate 17 bits (CF,r/m word) right
once
D3 /3 RCR r/m16,CL 9/10 Rotate 17 bits (CF,r/m word) right
CL times
C1 /3 ib RCR r/m16,imm8 9/10 Rotate 17 bits (CF,r/m word) right
imm8 times
D1 /3 RCR r/m32,1 9/10 Rotate 33 bits (CF,r/m dword) right
once
D3 /3 RCR r/m32,CL 9/10 Rotate 33 bits (CF,r/m dword) right
CL times
C1 /3 ib RCR r/m32,imm8 9/10 Rotate 33 bits (CF,r/m dword) right
imm8 times
D0 /0 ROL r/m8,1 3/7 Rotate 8 bits r/m byte left once
D2 /0 ROL r/m8,CL 3/7 Rotate 8 bits r/m byte left CL
times
C0 /0 ib ROL r/m8,imm8 3/7 Rotate 8 bits r/m byte left imm8
times
D1 /0 ROL r/m16,1 3/7 Rotate 16 bits r/m word left once
D3 /0 ROL r/m16,CL 3/7 Rotate 16 bits r/m word left CL
times
C1 /0 ib ROL r/m16,imm8 3/7 Rotate 16 bits r/m word left imm8
times
D1 /0 ROL r/m32,1 3/7 Rotate 32 bits r/m dword left once
D3 /0 ROL r/m32,CL 3/7 Rotate 32 bits r/m dword left CL
times
C1 /0 ib ROL r/m32,imm8 3/7 Rotate 32 bits r/m dword left imm8
times
D0 /1 ROR r/m8,1 3/7 Rotate 8 bits r/m byte right once
D2 /1 ROR r/m8,CL 3/7 Rotate 8 bits r/m byte right CL
times
C0 /1 ib ROR r/m8,imm8 3/7 Rotate 8 bits r/m word right imm8
times
D1 /1 ROR r/m16,1 3/7 Rotate 16 bits r/m word right once
D3 /1 ROR r/m16,CL 3/7 Rotate 16 bits r/m word right CL
times
C1 /1 ib ROR r/m16,imm8 3/7 Rotate 16 bits r/m word right imm8
times
D1 /1 ROR r/m32,1 3/7 Rotate 32 bits r/m dword right once
D3 /1 ROR r/m32,CL 3/7 Rotate 32 bits r/m dword right CL
times
C1 /1 ib ROR r/m32,imm8 3/7 Rotate 32 bits r/m dword right imm8
times
Operation
(* ROL - Rotate Left *)
temp  COUNT;
WHILE (temp <> 0)
DO
tmpcf  high-order bit of (r/m);
r/m  r/m * 2 + (tmpcf);
temp  temp - 1;
OD;
IF COUNT = 1
THEN
IF high-order bit of r/m <> CF
THEN OF  1;
ELSE OF  0;
FI;
ELSE OF  undefined;
FI;
(* ROR - Rotate Right *)
temp  COUNT;
WHILE (temp <> 0 )
DO
tmpcf  low-order bit of (r/m);
r/m  r/m / 2 + (tmpcf * 2^(width(r/m)));
temp  temp - 1;
DO;
IF COUNT = 1
THEN
IF (high-order bit of r/m) <> (bit next to high-order bit of r/m)
THEN OF  1;
ELSE OF  0;
FI;
ELSE OF  undefined;
FI;
Description
Each rotate instruction shifts the bits of the register or memory operand
given. The left rotate instructions shift all the bits upward, except for
the top bit, which is returned to the bottom. The right rotate instructions
do the reverse: the bits shift downward until the bottom bit arrives at
the top.
For the RCL and RCR instructions, the carry flag is part of the rotated
quantity. RCL shifts the carry flag into the bottom bit and shifts the top
bit into the carry flag; RCR shifts the carry flag into the top bit and
shifts the bottom bit into the carry flag. For the ROL and ROR
instructions, the original value of the carry flag is not a part of the
result, but the carry flag receives a copy of the bit that was shifted from
one end to the other.
The rotate is repeated the number of times indicated by the second
operand, which is either an immediate number or the contents of the CL
register. To reduce the maximum instruction execution time, the 80386
does not allow rotation counts greater than 31. If a rotation count greater
than 31 is attempted, only the bottom five bits of the rotation are used.
The 8086 does not mask rotation counts. The 80386 in Virtual 8086 Mode does
mask rotation counts.
The overflow flag is defined only for the single-rotate forms of the
instructions (second operand = 1). It is undefined in all other cases. For
left shifts/rotates, the CF bit after the shift is XORed with the
high-order result bit. For right shifts/rotates, the high-order two bits of
the result are XORed to get OF.
Flags Affected
OF only for single rotates; OF is undefined for multi-bit rotates; CF as
described above
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
REP/REPE/REPZ/REPNE/REPNZ ÄÄ Repeat Following String Operation
Opcode Instruction Clocks Description
F3 6C REP INS r/m8, DX 13+6*(E)CX,
pm=7+6*(E)CX
If CPL ó IOPL/
27+6*(E)CX
If CPL > IOPL or if in virtual 8086 mode Input (E)CX bytes from port
DX into ES:[(E)DI]
F3 6D REP INS r/m16,DX 13+6*(E)CX,
pm=7+6*(E)CX
If CPL ó IOPL/
27+6*(E)CX
If CPL > IOPL or if in virtual 8086 mode Input (E)CX words from port
DX into ES:[(E)DI]
F3 6D REP INS r/m32,DX 13+6*(E)CX,
pm=7+6*(E)CX
If CPL ó IOPL/
27+6*(E)CX
If CPL > IOPL or if in virtual 8086 mode Input (E)CX dwords from port
DX into ES:[(E)DI]
F3 A4 REP MOVS m8,m8 5+4*(E)CX Move (E)CX bytes from
[(E)SI] to ES:[(E)DI]
F3 A5 REP MOVS m16,m16 5+4*(E)CX Move (E)CX words from
[(E)SI] to ES:[(E)DI]
F3 A5 REP MOVS m32,m32 5+4*(E)CX Move (E)CX dwords from
[(E)SI] to ES:[(E)DI]
F3 6E REP OUTS DX,r/m8 5+12*(E)CX,
pm=6+5*(E)CX
If CPL ó IOPL/
26+5*(E)CX
If CPL > IOPL or if in virtual 8086 mode Output (E)CX bytes from
[(E)SI] to port DX
F3 6F REP OUTS DX,r/m16 5+12*(E)CX,
pm=6+5*(E)CX
If CPL ó IOPL/
26+5*(E)CX
If CPL > IOPL or if in virtual 8086 mode Output (E)CX words from
[(E)SI] to port DX
F3 6F REP OUTS DX,r/m32 5+12*(E)CX,
pm=6+5*(E)CX
If CPL ó IOPL/
26+5*(E)CX
If CPL > IOPL or if in virtual 8086 mode Output (E)CX dwords from
[(E)SI] to port DX
F3 AA REP STOS m8 5+5*(E)CX Fill (E)CX bytes at
ES:[(E)DI] with AL
F3 AB REP STOS m16 5+5*(E)CX Fill (E)CX words at
ES:[(E)DI] with AX
F3 AB REP STOS m32 5+5*(E)CX Fill (E)CX dwords at
ES:[(E)DI] with EAX
F3 A6 REPE CMPS m8,m8 5+9*N Find nonmatching bytes in
ES:[(E)DI] and [(E)SI]
F3 A7 REPE CMPS m16,m16 5+9*N Find nonmatching words in
ES:[(E)DI] and [(E)SI]
F3 A7 REPE CMPS m32,m32 5+9*N Find nonmatching dwords in
ES:[(E)DI] and [(E)SI]
F3 AE REPE SCAS m8 5+8*N Find non-AL byte starting
at ES:[(E)DI]
F3 AF REPE SCAS m16 5+8*N Find non-AX word starting
at ES:[(E)DI]
F3 AF REPE SCAS m32 5+8*N Find non-EAX dword starting
at ES:[(E)DI]
F2 A6 REPNE CMPS m8,m8 5+9*N Find matching bytes in
ES:[(E)DI] and [(E)SI]
F2 A7 REPNE CMPS m16,m16 5+9*N Find matching words in
ES:[(E)DI] and [(E)SI]
F2 A7 REPNE CMPS m32,m32 5+9*N Find matching dwords in
ES:[(E)DI] and [(E)SI]
F2 AE REPNE SCAS m8 5+8*N Find AL, starting at
ES:[(E)DI]
F2 AF REPNE SCAS m16 5+8*N Find AX, starting at
ES:[(E)DI]
F2 AF REPNE SCAS m32 5+8*N Find EAX, starting at
ES:[(E)DI]
Operation
IF AddressSize = 16
THEN use CX for CountReg;
ELSE (* AddressSize = 32 *) use ECX for CountReg;
FI;
WHILE CountReg <> 0
DO
service pending interrupts (if any);
perform primitive string instruction;
CountReg  CountReg - 1;
IF primitive operation is CMPB, CMPW, SCAB, or SCAW
THEN
IF (instruction is REP/REPE/REPZ) AND (ZF=1)
THEN exit WHILE loop
ELSE
IF (instruction is REPNZ or REPNE) AND (ZF=0)
THEN exit WHILE loop;
FI;
FI;
FI;
OD;
Description
REP, REPE (repeat while equal), and REPNE (repeat while not equal)
are prefix that are applied to string operation. Each prefix cause the
string instruction that follows to be repeated the number of times
indicated in the count register or (for REPE and REPNE) until the
indicated condition in the zero flag is no longer met.
Synonymous forms of REPE and REPNE are REPZ and REPNZ,
respectively.
The REP prefixes apply only to one string instruction at a time. To repeat
a block of instructions, use the LOOP instruction or another looping
construct.
The precise action for each iteration is as follows:
1. If the address-size attribute is 16 bits, use CX for the count
register; if the address-size attribute is 32 bits, use ECX for the
count register.
2. Check CX. If it is zero, exit the iteration, and move to the next
instruction.
3. Acknowledge any pending interrupts.
4. Perform the string operation once.
5. Decrement CX or ECX by one; no flags are modified.
6. Check the zero flag if the string operation is SCAS or CMPS. If
the repeat condition does not hold, exit the iteration and move to
the next instruction. Exit the iteration if the prefix is REPE and ZF
is 0 (the last comparison was not equal), or if the prefix is REPNE
and ZF is one (the last comparison was equal).
7. Return to step 1 for the next iteration.
Repeated CMPS and SCAS instructions can be exited if the count is
exhausted or if the zero flag fails the repeat condition. These two cases
can be distinguished by using either the JCXZ instruction, or by using
the conditional jumps that test the zero flag (JZ, JNZ, and JNE).
Flags Affected
ZF by REP CMPS and REP SCAS as described above
Protected Mode Exceptions
#UD if a repeat prefix is used before an instruction that is not in the
list above; further exceptions can be generated when the string operation is
executed; refer to the descriptions of the string instructions themselves
Real Address Mode Exceptions
Interrupt 6 if a repeat prefix is used before an instruction that is not in
the list above; further exceptions can be generated when the string
operation is executed; refer to the descriptions of the string instructions
themselves
Virtual 8086 Mode Exceptions
#UD if a repeat prefix is used before an instruction that is not in the
list above; further exceptions can be generated when the string operation is
executed; refer to the descriptions of the string instructions themselves
Notes
Not all input/output ports can handle the rate at which the REP INS
and REP OUTS instructions execute.
RET ÄÄ Return from Procedure
Opcode Instruction Clocks Description
C3 RET 10+m Return (near) to caller
CB RET 18+m,pm=32+m Return (far) to caller, same
privilege
CB RET pm=68 Return (far), lesser privilege,
switch stacks
C2 iw RET imm16 10+m Return (near), pop imm16 bytes of
parameters
CA iw RET imm16 18+m,pm=32+m Return (far), same privilege, pop
imm16 bytes
CA iw RET imm16 pm=68 Return (far), lesser privilege, pop
imm16 bytes
Operation
IF instruction = near RET
THEN;
IF OperandSize = 16
THEN
IP  Pop();
EIP  EIP AND 0000FFFFH;
ELSE (* OperandSize = 32 *)
EIP  Pop();
FI;
IF instruction has immediate operand THEN eSP  eSP + imm16; FI;
FI;
IF (PE = 0 OR (PE = 1 AND VM = 1))
(* real mode or virtual 8086 mode *)
AND instruction = far RET
THEN;
IF OperandSize = 16
THEN
IP  Pop();
EIP  EIP AND 0000FFFFH;
CS  Pop(); (* 16-bit pop *)
ELSE (* OperandSize = 32 *)
EIP  Pop();
CS  Pop(); (* 32-bit pop, high-order 16-bits discarded *)
FI;
IF instruction has immediate operand THEN eSP  eSP + imm16; FI;
FI;
IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)
AND instruction = far RET
THEN
IF OperandSize=32
THEN Third word on stack must be within stack limits else #SS(0);
ELSE Second word on stack must be within stack limits else #SS(0);
FI;
Return selector RPL must be ò CPL ELSE #GP(return selector)
IF return selector RPL = CPL
THEN GOTO SAME-LEVEL;
ELSE GOTO OUTER-PRIVILEGE-LEVEL;
FI;
FI;
SAME-LEVEL:
Return selector must be non-null ELSE #GP(0)
Selector index must be within its descriptor table limits ELSE
#GP(selector)
Descriptor AR byte must indicate code segment ELSE #GP(selector)
IF non-conforming
THEN code segment DPL must equal CPL;
ELSE #GP(selector);
FI;
IF conforming
THEN code segment DPL must be ó CPL;
ELSE #GP(selector);
FI;
Code segment must be present ELSE #NP(selector);
Top word on stack must be within stack limits ELSE #SS(0);
IP must be in code segment limit ELSE #GP(0);
IF OperandSize=32
THEN
Load CS:EIP from stack
Load CS register with descriptor
Increment eSP by 8 plus the immediate offset if it exists
ELSE (* OperandSize=16 *)
Load CS:IP from stack
Load CS register with descriptor
Increment eSP by 4 plus the immediate offset if it exists
FI;
OUTER-PRIVILEGE-LEVEL:
IF OperandSize=32
THEN Top (16+immediate) bytes on stack must be within stack limits
ELSE #SS(0);
ELSE Top (8+immediate) bytes on stack must be within stack limits ELSE
#SS(0);
FI;
Examine return CS selector and associated descriptor:
Selector must be non-null ELSE #GP(0);
Selector index must be within its descriptor table limits ELSE
#GP(selector)
Descriptor AR byte must indicate code segment ELSE #GP(selector);
IF non-conforming
THEN code segment DPL must equal return selector RPL
ELSE #GP(selector);
FI;
IF conforming
THEN code segment DPL must be ó return selector RPL;
ELSE #GP(selector);
FI;
Segment must be present ELSE #NP(selector)
Examine return SS selector and associated descriptor:
Selector must be non-null ELSE #GP(0);
Selector index must be within its descriptor table limits
ELSE #GP(selector);
Selector RPL must equal the RPL of the return CS selector ELSE
#GP(selector);
Descriptor AR byte must indicate a writable data segment ELSE
#GP(selector);
Descriptor DPL must equal the RPL of the return CS selector ELSE
#GP(selector);
Segment must be present ELSE #NP(selector);
IP must be in code segment limit ELSE #GP(0);
Set CPL to the RPL of the return CS selector;
IF OperandMode=32
THEN
Load CS:EIP from stack;
Set CS RPL to CPL;
Increment eSP by 8 plus the immediate offset if it exists;
Load SS:eSP from stack;
ELSE (* OperandMode=16 *)
Load CS:IP from stack;
Set CS RPL to CPL;
Increment eSP by 4 plus the immediate offset if it exists;
Load SS:eSP from stack;
FI;
Load the CS register with the return CS descriptor;
Load the SS register with the return SS descriptor;
For each of ES, FS, GS, and DS
DO
IF the current register setting is not valid for the outer level,
set the register to null (selector  AR  0);
To be valid, the register setting must satisfy the following
properties:
Selector index must be within descriptor table limits;
Descriptor AR byte must indicate data or readable code segment;
IF segment is data or non-conforming code, THEN
DPL must be ò CPL, or DPL must be ò RPL;
FI;
OD;
Description
RET transfers control to a return address located on the stack. The
address is usually placed on the stack by a CALL instruction, and the
return is made to the instruction that follows the CALL.
The optional numeric parameter to RET gives the number of stack bytes
(OperandMode=16) or words (OperandMode=32) to be released after the return
address is popped. These items are typically used as input parameters to the
procedure called.
For the intrasegment (near) return, the address on the stack is a segment
offset, which is popped into the instruction pointer. The CS register is
unchanged. For the intersegment (far) return, the address on the stack
is a long pointer. The offset is popped first, followed by the selector.
In real mode, CS and IP are loaded directly. In Protected Mode, an
intersegment return causes the processor to check the descriptor
addressed by the return selector. The AR byte of the descriptor must
indicate a code segment of equal or lesser privilege (or greater or equal
numeric value) than the current privilege level. Returns to a lesser
privilege level cause the stack to be reloaded from the value saved beyond
the parameter block.
The DS, ES, FS, and GS segment registers can be set to 0 by the RET
instruction during an interlevel transfer. If these registers refer to
segments that cannot be used by the new privilege level, they are set to
0 to prevent unauthorized access from the new privilege level.
Flags Affected
None
Protected Mode Exceptions
#GP, #NP, or #SS, as described under "Operation" above; #PF(fault-code) for
a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would be outside the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
SAHF ÄÄ Store AH into Flags
Opcode Instruction Clocks Description
9E SAHF 3 Store AH into flags SF ZF xx AF xx PF xx CF
Operation
SF:ZF:xx:AF:xx:PF:xx:CF  AH;
Description
SAHF loads the flags listed above with values from the AH register,
from bits 7, 6, 4, 2, and 0, respectively.
Flags Affected
SF, ZF, AF, PF, and CF as described above
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
SAL/SAR/SHL/SHR ÄÄ Shift Instructions
Opcode Instruction Clocks Description
D0 /4 SAL r/m8,1 3/7 Multiply r/m byte by 2, once
D2 /4 SAL r/m8,CL 3/7 Multiply r/m byte by 2, CL times
C0 /4 ib SAL r/m8,imm8 3/7 Multiply r/m byte by 2, imm8
times
D1 /4 SAL r/m16,1 3/7 Multiply r/m word by 2, once
D3 /4 SAL r/m16,CL 3/7 Multiply r/m word by 2, CL times
C1 /4 ib SAL r/m16,imm8 3/7 Multiply r/m word by 2, imm8
times
D1 /4 SAL r/m32,1 3/7 Multiply r/m dword by 2, once
D3 /4 SAL r/m32,CL 3/7 Multiply r/m dword by 2, CL
times
C1 /4 ib SAL r/m32,imm8 3/7 Multiply r/m dword by 2, imm8
times
D0 /7 SAR r/m8,1 3/7 Signed divide^(1) r/m byte by 2,
once
D2 /7 SAR r/m8,CL 3/7 Signed divide^(1) r/m byte by 2,
CL times
C0 /7 ib SAR r/m8,imm8 3/7 Signed divide^(1) r/m byte by 2,
imm8 times
D1 /7 SAR r/m16,1 3/7 Signed divide^(1) r/m word by 2,
once
D3 /7 SAR r/m16,CL 3/7 Signed divide^(1) r/m word by 2,
CL times
C1 /7 ib SAR r/m16,imm8 3/7 Signed divide^(1) r/m word by 2,
imm8 times
D1 /7 SAR r/m32,1 3/7 Signed divide^(1) r/m dword by 2,
once
D3 /7 SAR r/m32,CL 3/7 Signed divide^(1) r/m dword by 2,
CL times
C1 /7 ib SAR r/m32,imm8 3/7 Signed divide^(1) r/m dword by 2,
imm8 times
D0 /4 SHL r/m8,1 3/7 Multiply r/m byte by 2, once
D2 /4 SHL r/m8,CL 3/7 Multiply r/m byte by 2, CL times
C0 /4 ib SHL r/m8,imm8 3/7 Multiply r/m byte by 2, imm8
times
D1 /4 SHL r/m16,1 3/7 Multiply r/m word by 2, once
D3 /4 SHL r/m16,CL 3/7 Multiply r/m word by 2, CL times
C1 /4 ib SHL r/m16,imm8 3/7 Multiply r/m word by 2, imm8
times
D1 /4 SHL r/m32,1 3/7 Multiply r/m dword by 2, once
D3 /4 SHL r/m32,CL 3/7 Multiply r/m dword by 2, CL
times
C1 /4 ib SHL r/m32,imm8 3/7 Multiply r/m dword by 2, imm8
times
D0 /5 SHR r/m8,1 3/7 Unsigned divide r/m byte by 2,
once
D2 /5 SHR r/m8,CL 3/7 Unsigned divide r/m byte by 2,
CL times
C0 /5 ib SHR r/m8,imm8 3/7 Unsigned divide r/m byte by 2,
imm8 times
D1 /5 SHR r/m16,1 3/7 Unsigned divide r/m word by 2,
once
D3 /5 SHR r/m16,CL 3/7 Unsigned divide r/m word by 2,
CL times
C1 /5 ib SHR r/m16,imm8 3/7 Unsigned divide r/m word by 2,
imm8 times
D1 /5 SHR r/m32,1 3/7 Unsigned divide r/m dword by 2,
once
D3 /5 SHR r/m32,CL 3/7 Unsigned divide r/m dword by 2,
CL times
C1 /5 ib SHR r/m32,imm8 3/7 Unsigned divide r/m dword by 2,
imm8 times
Not the same division as IDIV; rounding is toward negative infinity.
Operation
(* COUNT is the second parameter *)
(temp)  COUNT;
WHILE (temp <> 0)
DO
IF instruction is SAL or SHL
THEN CF  high-order bit of r/m;
FI;
IF instruction is SAR or SHR
THEN CF  low-order bit of r/m;
FI;
IF instruction = SAL or SHL
THEN r/m  r/m * 2;
FI;
IF instruction = SAR
THEN r/m  r/m /2 (*Signed divide, rounding toward negative infinity*);
FI;
IF instruction = SHR
THEN r/m  r/m / 2; (* Unsigned divide *);
FI;
temp  temp - 1;
OD;
(* Determine overflow for the various instructions *)
IF COUNT = 1
THEN
IF instruction is SAL or SHL
THEN OF  high-order bit of r/m <> (CF);
FI;
IF instruction is SAR
THEN OF  0;
FI;
IF instruction is SHR
THEN OF  high-order bit of operand;
FI;
ELSE OF  undefined;
FI;
Description
SAL (or its synonym, SHL) shifts the bits of the operand upward. The
high-order bit is shifted into the carry flag, and the low-order bit is set
to 0.
SAR and SHR shift the bits of the operand downward. The low-order
bit is shifted into the carry flag. The effect is to divide the operand by
2. SAR performs a signed divide with rounding toward negative infinity (not
the same as IDIV); the high-order bit remains the same. SHR performs an
unsigned divide; the high-order bit is set to 0.
The shift is repeated the number of times indicated by the second
operand, which is either an immediate number or the contents of the CL
register. To reduce the maximum execution time, the 80386 does not
allow shift counts greater than 31. If a shift count greater than 31 is
attempted, only the bottom five bits of the shift count are used. (The
8086 uses all eight bits of the shift count.)
The overflow flag is set only if the single-shift forms of the instructions
are used. For left shifts, OF is set to 0 if the high bit of the answer is
the same as the result of the carry flag (i.e., the top two bits of the
original operand were the same); OF is set to 1 if they are different. For
SAR, OF is set to 0 for all single shifts. For SHR, OF is set to the
high-order bit of the original operand.
Flags Affected
OF for single shifts; OF is undefined for multiple shifts; CF, ZF, PF,
and SF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
SBB ÄÄ Integer Subtraction with Borrow
Opcode Instruction Clocks Description
1C ib SBB AL,imm8 2 Subtract with borrow immediate byte
from AL
1D iw SBB AX,imm16 2 Subtract with borrow immediate word
from AX
1D id SBB EAX,imm32 2 Subtract with borrow immediate
dword from EAX
80 /3 ib SBB r/m8,imm8 2/7 Subtract with borrow immediate byte
from r/m byte
81 /3 iw SBB r/m16,imm16 2/7 Subtract with borrow immediate word
from r/m word
81 /3 id SBB r/m32,imm32 2/7 Subtract with borrow immediate
dword from r/m dword
83 /3 ib SBB r/m16,imm8 2/7 Subtract with borrow sign-extended
immediate byte from r/m word
83 /3 ib SBB r/m32,imm8 2/7 Subtract with borrow sign-extended
immediate byte from r/m dword
18 /r SBB r/m8,r8 2/6 Subtract with borrow byte register
from r/m byte
19 /r SBB r/m16,r16 2/6 Subtract with borrow word register
from r/m word
19 /r SBB r/m32,r32 2/6 Subtract with borrow dword register
from r/m dword
1A /r SBB r8,r/m8 2/7 Subtract with borrow byte register
from r/m byte
1B /r SBB r16,r/m16 2/7 Subtract with borrow word register
from r/m word
1B /r SBB r32,r/m32 2/7 Subtract with borrow dword register
from r/m dword
Operation
IF SRC is a byte and DEST is a word or dword
THEN DEST = DEST - (SignExtend(SRC) + CF)
ELSE DEST  DEST - (SRC + CF);
Description
SBB adds the second operand (DEST) to the carry flag (CF) and
subtracts the result from the first operand (SRC). The result of the
subtraction is assigned to the first operand (DEST), and the flags are
set accordingly.
When an immediate byte value is subtracted from a word operand, the
immediate value is first sign-extended.
Flags Affected
OF, SF, ZF, AF, PF, and CF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
SCAS/SCASB/SCASW/SCASD ÄÄ Compare String Data
Opcode Instruction Clocks Description
AE SCAS m8 7 Compare bytes AL-ES:[DI], update (E)DI
AF SCAS m16 7 Compare words AX-ES:[DI], update (E)DI
AF SCAS m32 7 Compare dwords EAX-ES:[DI], update (E)DI
AE SCASB 7 Compare bytes AL-ES:[DI], update (E)DI
AF SCASW 7 Compare words AX-ES:[DI], update (E)DI
AF SCASD 7 Compare dwords EAX-ES:[DI], update (E)DI
Operation
IF AddressSize = 16
THEN use DI for dest-index;
ELSE (* AddressSize = 32 *) use EDI for dest-index;
FI;
IF byte type of instruction
THEN
AL - [dest-index]; (* Compare byte in AL and dest *)
IF DF = 0 THEN IndDec  1 ELSE IncDec  -1; FI;
ELSE
IF OperandSize = 16
THEN
AX - [dest-index]; (* compare word in AL and dest *)
IF DF = 0 THEN IncDec  2 ELSE IncDec  -2; FI;
ELSE (* OperandSize = 32 *)
EAX - [dest-index];(* compare dword in EAX & dest *)
IF DF = 0 THEN IncDec  4 ELSE IncDec  -4; FI;
FI;
FI;
dest-index = dest-index + IncDec
Description
SCAS subtracts the memory byte or word at the destination register from
the AL, AX or EAX register. The result is discarded; only the flags are set.
The operand must be addressable from the ES segment; no segment override is
possible.
If the address-size attribute for this instruction is 16 bits, DI is used
as the destination register; otherwise, the address-size attribute is 32
bits and EDI is used.
The address of the memory data being compared is determined solely by the
contents of the destination register, not by the operand to SCAS. The
operand validates ES segment addressability and determines the data type.
Load the correct index value into DI or EDI before executing SCAS.
After the comparison is made, the destination register is automatically
updated. If the direction flag is 0 (CLD was executed), the destination
register is incremented; if the direction flag is 1 (STD was executed), it
is decremented. The increments or decrements are by 1 if bytes are compared,
by 2 if words are compared, or by 4 if doublewords are compared.
SCASB, SCASW, and SCASD are synonyms for the byte, word and
doubleword SCAS instructions that don't require operands. They are
simpler to code, but provide no type or segment checking.
SCAS can be preceded by the REPE or REPNE prefix for a block search
of CX or ECX bytes or words. Refer to the REP instruction for further
details.
Flags Affected
OF, SF, ZF, AF, PF, and CF as described in Appendix C
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
SETcc ÄÄ Byte Set on Condition
Opcode Instruction Clocks Description
0F 97 SETA r/m8 4/5 Set byte if above (CF=0 and ZF=0)
0F 93 SETAE r/m8 4/5 Set byte if above or equal (CF=0)
0F 92 SETB r/m8 4/5 Set byte if below (CF=1)
0F 96 SETBE r/m8 4/5 Set byte if below or equal (CF=1 or (ZF=1)
0F 92 SETC r/m8 4/5 Set if carry (CF=1)
0F 94 SETE r/m8 4/5 Set byte if equal (ZF=1)
0F 9F SETG r/m8 4/5 Set byte if greater (ZF=0 or SF=OF)
0F 9D SETGE r/m8 4/5 Set byte if greater or equal (SF=OF)
0F 9C SETL r/m8 4/5 Set byte if less (SF<>OF)
0F 9E SETLE r/m8 4/5 Set byte if less or equal (ZF=1 and
SF<>OF)
0F 96 SETNA r/m8 4/5 Set byte if not above (CF=1)
0F 92 SETNAE r/m8 4/5 Set byte if not above or equal (CF=1)
0F 93 SETNB r/m8 4/5 Set byte if not below (CF=0)
0F 97 SETNBE r/m8 4/5 Set byte if not below or equal (CF=0 and
ZF=0)
0F 93 SETNC r/m8 4/5 Set byte if not carry (CF=0)
0F 95 SETNE r/m8 4/5 Set byte if not equal (ZF=0)
0F 9E SETNG r/m8 4/5 Set byte if not greater (ZF=1 or SF<>OF)
0F 9C SETNGE r/m8 4/5 Set if not greater or equal (SF<>OF)
0F 9D SETNL r/m8 4/5 Set byte if not less (SF=OF)
0F 9F SETNLE r/m8 4/5 Set byte if not less or equal (ZF=1 and
SF<>OF)
0F 91 SETNO r/m8 4/5 Set byte if not overflow (OF=0)
0F 9B SETNP r/m8 4/5 Set byte if not parity (PF=0)
0F 99 SETNS r/m8 4/5 Set byte if not sign (SF=0)
0F 95 SETNZ r/m8 4/5 Set byte if not zero (ZF=0)
0F 90 SETO r/m8 4/5 Set byte if overflow (OF=1)
0F 9A SETP r/m8 4/5 Set byte if parity (PF=1)
0F 9A SETPE r/m8 4/5 Set byte if parity even (PF=1)
0F 9B SETPO r/m8 4/5 Set byte if parity odd (PF=0)
0F 98 SETS r/m8 4/5 Set byte if sign (SF=1)
0F 94 SETZ r/m8 4/5 Set byte if zero (ZF=1)
Operation
IF condition THEN r/m8  1 ELSE r/m8  0; FI;
Description
SETcc stores a byte at the destination specified by the effective address
or register if the condition is met, or a 0 byte if the condition is not
met.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a non-writable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
SGDT/SIDT ÄÄ Store Global/Interrupt Descriptor Table Register
Opcode Instruction Clocks Description
0F 01 /0 SGDT m 9 Store GDTR to m
0F 01 /1 SIDT m 9 Store IDTR to m
Operation
DEST  48-bit BASE/LIMIT register contents;
Description
SGDT/SIDT copies the contents of the descriptor table register the six
bytes of memory indicated by the operand. The LIMIT field of the
register is assigned to the first word at the effective address. If the
operand-size attribute is 32 bits, the next three bytes are assigned the
BASE field of the register, and the fourth byte is written with zero. The
last byte is undefined. Otherwise, if the operand-size attribute is 16
bits, the next four bytes are assigned the 32-bit BASE field of the
register.
SGDT and SIDT are used only in operating system software; they are
not used in application programs.
Flags Affected
None
Protected Mode Exceptions
Interrupt 6 if the destination operand is a register; #GP(0) if the
destination is in a nonwritable segment; #GP(0) for an illegal memory
operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for
an illegal address in the SS segment; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 6 if the destination operand is a register; Interrupt 13 if any
part of the operand would lie outside of the effective address space from
0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
Compatability Note
The 16-bit forms of the SGDT/SIDT instructions are compatible with
the 80286, if the value in the upper eight bits is not referenced. The
80286 stores 1's in these upper bits, whereas the 80386 stores 0's if the
operand-size attribute is 16 bits. These bits were specified as undefined
by the SGDT/SIDT instructions in the iAPX 286 Programmer's
Reference Manual.
SHLD ÄÄ Double Precision Shift Left
Opcode Instruction Clocks Description
0F A4 SHLD r/m16,r16,imm8 3/7 r/m16 gets SHL of r/m16 concatenated
with r16
0F A4 SHLD r/m32,r32,imm8 3/7 r/m32 gets SHL of r/m32 concatenated
with r32
0F A5 SHLD r/m16,r16,CL 3/7 r/m16 gets SHL of r/m16 concatenated
with r16
0F A5 SHLD r/m32,r32,CL 3/7 r/m32 gets SHL of r/m32 concatenated
with r32
Operation
(* count is an unsigned integer corresponding to the last operand of the
instruction, either an immediate byte or the byte in register CL *)
ShiftAmt  count MOD 32;
inBits  register; (* Allow overlapped operands *)
IF ShiftAmt = 0
THEN no operation
ELSE
IF ShiftAmt ò OperandSize
THEN (* Bad parameters *)
r/m  UNDEFINED;
CF, OF, SF, ZF, AF, PF  UNDEFINED;
ELSE (* Perform the shift *)
CF  BIT[Base, OperandSize - ShiftAmt];
(* Last bit shifted out on exit *)
FOR i  OperandSize - 1 DOWNTO ShiftAmt
DO
BIT[Base, i]  BIT[Base, i - ShiftAmt];
OF;
FOR i  ShiftAmt - 1 DOWNTO 0
DO
BIT[Base, i]  BIT[inBits, i - ShiftAmt + OperandSize];
OD;
Set SF, ZF, PF (r/m);
(* SF, ZF, PF are set according to the value of the result *)
AF  UNDEFINED;
FI;
FI;
Description
SHLD shifts the first operand provided by the r/m field to the left as
many bits as specified by the count operand. The second operand (r16 or r32)
provides the bits to shift in from the right (starting with bit 0). The
result is stored back into the r/m operand. The register remains unaltered.
The count operand is provided by either an immediate byte or the contents
of the CL register. These operands are taken MODULO 32 to provide a number
between 0 and 31 by which to shift. Because the bits to shift are provided
by the specified registers, the operation is useful for multiprecision
shifts (64 bits or more). The SF, ZF and PF flags are set according to the
value of the result. CS is set to the value of the last bit shifted out. OF
and AF are left undefined.
Flags Affected
OF, SF, ZF, PF, and CF as described above; AF and OF are undefined
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
SHRD ÄÄ Double Precision Shift Right
Opcode Instruction Clocks Description
0F AC SHRD r/m16,r16,imm8 3/7 r/m16 gets SHR of r/m16 concatenated
with r16
0F AC SHRD r/m32,r32,imm8 3/7 r/m32 gets SHR of r/m32 concatenated
with r32
0F AD SHRD r/m16,r16,CL 3/7 r/m16 gets SHR of r/m16 concatenated
with r16
0F AD SHRD r/m32,r32,CL 3/7 r/m32 gets SHR of r/m32 concatenated
with r32
Operation
(* count is an unsigned integer corresponding to the last operand of the
instruction, either an immediate byte or the byte in register CL *)
ShiftAmt  count MOD 32;
inBits  register; (* Allow overlapped operands *)
IF ShiftAmt = 0
THEN no operation
ELSE
IF ShiftAmt ò OperandSize
THEN (* Bad parameters *)
r/m  UNDEFINED;
CF, OF, SF, ZF, AF, PF  UNDEFINED;
ELSE (* Perform the shift *)
CF  BIT[r/m, ShiftAmt - 1]; (* last bit shifted out on exit *)
FOR i  0 TO OperandSize - 1 - ShiftAmt
DO
BIT[r/m, i]  BIT[r/m, i - ShiftAmt];
OD;
FOR i  OperandSize - ShiftAmt TO OperandSize - 1
DO
BIT[r/m,i]  BIT[inBits,i+ShiftAmt - OperandSize];
OD;
Set SF, ZF, PF (r/m);
(* SF, ZF, PF are set according to the value of the result *)
Set SF, ZF, PF (r/m);
AF  UNDEFINED;
FI;
FI;
Description
SHRD shifts the first operand provided by the r/m field to the right as many
bits as specified by the count operand. The second operand (r16 or r32)
provides the bits to shift in from the left (starting with bit 31). The
result is stored back into the r/m operand. The register remains unaltered.
The count operand is provided by either an immediate byte or the contents
of the CL register. These operands are taken MODULO 32 to provide a number
between 0 and 31 by which to shift. Because the bits to shift are provided
by the specified register, the operation is useful for multi-precision
shifts (64 bits or more). The SF, ZF and PF flags are set according to the
value of the result. CS is set to the value of the last bit shifted out. OF
and AF are left undefined.
Flags Affected
OF, SF, ZF, PF, and CF as described above; AF and OF are undefined
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
SLDT ÄÄ Store Local Descriptor Table Register
Opcode Instruction Clocks Description
0F 00 /0 SLDT r/m16 pm=2/2 Store LDTR to EA word
Operation
r/m16  LDTR;
Description
SLDT stores the Local Descriptor Table Register (LDTR) in the two-byte
register or memory location indicated by the effective address operand.
This register is a selector that points into the Global Descriptor Table.
SLDT is used only in operating system software. It is not used in
application programs.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 6; SLDT is not recognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
Notes
The operand-size attribute has no effect on the operation of the
instruction.
SMSW ÄÄ Store Machine Status Word
Opcode Instruction Clocks Description
0F 01 /4 SMSW r/m16 2/3,pm=2/2 Store machine status word to EA
word
Operation
r/m16  MSW;
Description
SMSW stores the machine status word (part of CR0) in the two-byte register
or memory location indicated by the effective address operand.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
Notes
This instruction is provided for compatibility with the 80286; 80386
programs should use MOV ..., CR0.
STC ÄÄ Set Carry Flag
Opcode Instruction Clocks Description
F9 STC 2 Set carry flag
Operation
CF  1;
Description
STC sets the carry flag to 1.
Flags Affected
CF = 1
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
STD ÄÄ Set Direction Flag
Opcode Instruction Clocks Description
FD STD 2 Set direction flag so (E)SI and/or (E)DI
decrement
Operation
DF  1;
Description
STD sets the direction flag to 1, causing all subsequent string operations
to decrement the index registers, (E)SI and/or (E)DI, on which they
operate.
Flags Affected
DF = 1
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
STI ÄÄ Set Interrupt Flag
Opcode Instruction Clocks Description
F13 STI 3 Set interrupt flag; interrupts enabled at the
end of the next instruction
Operation
IF  1
Description
STI sets the interrupt flag to 1. The 80386 then responds to external
interrupts after executing the next instruction if the next instruction
allows the interrupt flag to remain enabled. If external interrupts are
disabled and you code STI, RET (such as at the end of a subroutine),
the RET is allowed to execute before external interrupts are recognized.
Also, if external interrupts are disabled and you code STI, CLI, then
external interrupts are not recognized because the CLI instruction clears
the interrupt flag during its execution.
Flags Affected
IF = 1
Protected Mode Exceptions
#GP(0) if the current privilege level is greater (has less privilege) than
the I/O privilege level
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
STOS/STOSB/STOSW/STOSD ÄÄ Store String Data
Opcode Instruction Clocks Description
AA STOS m8 4 Store AL in byte ES:[(E)DI], update (E)DI
AB STOS m16 4 Store AX in word ES:[(E)DI], update (E)DI
AB STOS m32 4 Store EAX in dword ES:[(E)DI], update (E)DI
AA STOSB 4 Store AL in byte ES:[(E)DI], update (E)DI
AB STOSW 4 Store AX in word ES:[(E)DI], update (E)DI
AB STOSD 4 Store EAX in dword ES:[(E)DI], update (E)DI
Operation
IF AddressSize = 16
THEN use ES:DI for DestReg
ELSE (* AddressSize = 32 *) use ES:EDI for DestReg;
FI;
IF byte type of instruction
THEN
(ES:DestReg)  AL;
IF DF = 0
THEN DestReg  DestReg + 1;
ELSE DestReg  DestReg - 1;
FI;
ELSE IF OperandSize = 16
THEN
(ES:DestReg)  AX;
IF DF = 0
THEN DestReg  DestReg + 2;
ELSE DestReg  DestReg - 2;
FI;
ELSE (* OperandSize = 32 *)
(ES:DestReg)  EAX;
IF DF = 0
THEN DestReg  DestReg + 4;
ELSE DestReg  DestReg - 4;
FI;
FI;
FI;
Description
STOS transfers the contents of all AL, AX, or EAX register to the memory
byte or word given by the destination register relative to the ES segment.
The destination register is DI for an address-size attribute of 16 bits or
EDI for an address-size attribute of 32 bits.
The destination operand must be addressable from the ES register. A segment
override is not possible.
The address of the destination is determined by the contents of the
destination register, not by the explicit operand of STOS. This operand is
used only to validate ES segment addressability and to determine the data
type. Load the correct index value into the destination register before
executing STOS.
After the transfer is made, DI is automatically updated. If the direction
flag is 0 (CLD was executed), DI is incremented; if the direction flag is
1 (STD was executed), DI is decremented. DI is incremented or decremented by
1 if a byte is stored, by 2 if a word is stored, or by 4 if a doubleword is
stored.
STOSB, STOSW, and STOSD are synonyms for the byte, word, and doubleword STOS
instructions, that do not require an operand. They are simpler to use, but
provide no type or segment checking.
STOS can be preceded by the REP prefix for a block fill of CX or ECX bytes,
words, or doublewords. Refer to the REP instruction for further details.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
STR ÄÄ Store Task Register
Opcode Instruction Clocks Description
0F 00 /1 STR r/m16 pm=23/27 Load EA word into task register
Operation
r/m  task register;
Description
The contents of the task register are copied to the two-byte register or
memory location indicated by the effective address operand.
STR is used only in operating system software. It is not used in application
programs.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 6; STR is not recognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode
Notes
The operand-size attribute has no effect on this instruction.
SUB ÄÄ Integer Subtraction
Opcode Instruction Clocks Description
2C ib SUB AL,imm8 2 Subtract immediate byte from AL
2D iw SUB AX,imm16 2 Subtract immediate word from AX
2D id SUB EAX,imm32 2 Subtract immediate dword from EAX
80 /5 ib SUB r/m8,imm8 2/7 Subtract immediate byte from r/m byte
81 /5 iw SUB r/m16,imm16 2/7 Subtract immediate word from r/m word
81 /5 id SUB r/m32,imm32 2/7 Subtract immediate dword from r/m
dword
83 /5 ib SUB r/m16,imm8 2/7 Subtract sign-extended immediate byte
from r/m word
83 /5 ib SUB r/m32,imm8 2/7 Subtract sign-extended immediate byte
from r/m dword
28 /r SUB r/m8,r8 2/6 Subtract byte register from r/m byte
29 /r SUB r/m16,r16 2/6 Subtract word register from r/m word
29 /r SUB r/m32,r32 2/6 Subtract dword register from r/m
dword
2A /r SUB r8,r/m8 2/7 Subtract byte register from r/m byte
2B /r SUB r16,r/m16 2/7 Subtract word register from r/m word
2B /r SUB r32,r/m32 2/7 Subtract dword register from r/m
dword
Operation
IF SRC is a byte and DEST is a word or dword
THEN DEST = DEST - SignExtend(SRC);
ELSE DEST  DEST - SRC;
FI;
Description
SUB subtracts the second operand (SRC) from the first operand (DEST). The
first operand is assigned the result of the subtraction, and the flags are
set accordingly.
When an immediate byte value is subtracted from a word operand, the
immediate value is first sign-extended to the size of the destination
operand.
Flags Affected
OF, SF, ZF, AF, PF, and CF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
TEST ÄÄ Logical Compare
Opcode Instruction Clocks Description
A8 ib TEST AL,imm8 2 AND immediate byte with AL
A9 iw TEST AX,imm16 2 AND immediate word with AX
A9 id TEST EAX,imm32 2 AND immediate dword with EAX
F6 /0 ib TEST r/m8,imm8 2/5 AND immediate byte with r/m byte
F7 /0 iw TEST r/m16,imm16 2/5 AND immediate word with r/m word
F7 /0 id TEST r/m32,imm32 2/5 AND immediate dword with r/m dword
84 /r TEST r/m8,r8 2/5 AND byte register with r/m byte
85 /r TEST r/m16,r16 2/5 AND word register with r/m word
85 /r TEST r/m32,r32 2/5 AND dword register with r/m dword
Operation
DEST : = LeftSRC AND RightSRC;
CF  0;
OF  0;
Description
TEST computes the bit-wise logical AND of its two operands. Each bit
of the result is 1 if both of the corresponding bits of the operands are 1;
otherwise, each bit is 0. The result of the operation is discarded and only
the flags are modified.
Flags Affected
OF = 0, CF = 0; SF, ZF, and PF as described in Appendix C
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
VERR, VERW ÄÄ Verify a Segment for Reading or Writing
Opcode Instruction Clocks Description
0F 00 /4 VERR r/m16 pm=10/11 Set ZF=1 if segment can be read,
selector in r/m16
0F 00 /5 VERW r/m16 pm=15/16 Set ZF=1 if segment can be written,
selector in r/m16
Operation
IF segment with selector at (r/m) is accessible
with current protection level
AND ((segment is readable for VERR) OR
(segment is writable for VERW))
THEN ZF  0;
ELSE ZF  1;
FI;
Description
The two-byte register or memory operand of VERR and VERW contains
the value of a selector. VERR and VERW determine whether the
segment denoted by the selector is reachable from the current privilege
level and whether the segment is readable (VERR) or writable (VERW).
If the segment is accessible, the zero flag is set to 1; if the segment is
not accessible, the zero flag is set to 0. To set ZF, the following
conditions must be met:
þ The selector must denote a descriptor within the bounds of the table
(GDT or LDT); the selector must be "defined."
þ The selector must denote the descriptor of a code or data segment
(not that of a task state segment, LDT, or a gate).
þ For VERR, the segment must be readable. For VERW, the segment
must be a writable data segment.
þ If the code segment is readable and conforming, the descriptor
privilege level (DPL) can be any value for VERR. Otherwise, the
DPL must be greater than or equal to (have less or the same
privilege as) both the current privilege level and the selector's RPL.
The validation performed is the same as if the segment were loaded into
DS, ES, FS, or GS, and the indicated access (read or write) were
performed. The zero flag receives the result of the validation. The
selector's value cannot result in a protection exception, enabling the
software to anticipate possible segment access problems.
Flags Affected
ZF as described above
Protected Mode Exceptions
Faults generated by illegal addressing of the memory operand that
contains the selector, the selector is not loaded into any segment
register, and no faults attributable to the selector operand are generated
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 6; VERR and VERW are not recognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
WAIT ÄÄ Wait until BUSY# Pin is Inactive (HIGH)
Opcode Instruction Clocks Description
9B WAIT 6 min. Wait until BUSY pin is inactive (HIGH)
Description
WAIT suspends execution of 80386 instructions until the BUSY# pin is
inactive (high). The BUSY# pin is driven by the 80287 numeric processor
extension.
Flags Affected
None
Protected Mode Exceptions
#NM if the task-switched flag in the machine status word (the lower 16 bits
of register CR0) is set; #MF if the ERROR# input pin is asserted (i.e., the
80287 has detected an unmasked numeric error)
Real Address Mode Exceptions
Same exceptions as in Protected Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Protected Mode
XCHG ÄÄ Exchange Register/Memory with Register
Opcode Instruction Clocks Description
90 + r XCHG AX,r16 3 Exchange word register with AX
90 + r XCHG r16,AX 3 Exchange word register with AX
90 + r XCHG EAX,r32 3 Exchange dword register with EAX
90 + r XCHG r32,EAX 3 Exchange dword register with EAX
86 /r XCHG r/m8,r8 3 Exchange byte register with EA byte
86 /r XCHG r8,r/m8 3/5 Exchange byte register with EA byte
87 /r XCHG r/m16,r16 3 Exchange word register with EA word
87 /r XCHG r16,r/m16 3/5 Exchange word register with EA word
87 /r XCHG r/m32,r32 3 Exchange dword register with EA dword
87 /r XCHG r32,r/m32 3/5 Exchange dword register with EA dword
Operation
temp  DEST
DEST  SRC
SRC  temp
Description
XCHG exchanges two operands. The operands can be in either order. If a
memory operand is involved, BUS LOCK is asserted for the duration of the
exchange, regardless of the presence or absence of the LOCK prefix or of the
value of the IOPL.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if either operand is in a nonwritable segment; #GP(0) for an
illegal memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code)
for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
XLAT/XLATB ÄÄ Table Look-up Translation
D7 XLAT m8 5 Set AL to memory byte DS:[(E)BX + unsigned AL]
D7 XLATB 5 Set AL to memory byte DS:[(E)BX + unsigned AL]
Operation
IF AddressSize = 16
THEN
AL  (BX + ZeroExtend(AL))
ELSE (* AddressSize = 32 *)
AL  (EBX + ZeroExtend(AL));
FI;
Description
XLAT changes the AL register from the table index to the table entry. AL
should be the unsigned index into a table addressed by DS:BX (for an
address-size attribute of 16 bits) or DS:EBX (for an address-size attribute
of 32 bits).
The operand to XLAT allows for the possibility of a segment override. XLAT
uses the contents of BX even if they differ from the offset of the operand.
The offset of the operand should have been moved intoBX/EBX with a previous
instruction.
The no-operand form, XLATB, can be used if the BX/EBX table will always
reside in the DS segment.
Flags Affected
None
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS, ES,
FS, or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
XOR ÄÄ Logical Exclusive OR
Opcode Instruction Clocks Description
34 ib XOR AL,imm8 2 Exclusive-OR immediate byte to AL
35 iw XOR AX,imm16 2 Exclusive-OR immediate word to AX
35 id XOR EAX,imm32 2 Exclusive-OR immediate dword to EAX
80 /6 ib XOR r/m8,imm8 2/7 Exclusive-OR immediate byte to r/m
byte
81 /6 iw XOR r/m16,imm16 2/7 Exclusive-OR immediate word to r/m
word
81 /6 id XOR r/m32,imm32 2/7 Exclusive-OR immediate dword to r/m
dword
83 /6 ib XOR r/m16,imm8 2/7 XOR sign-extended immediate byte
with r/m word
83 /6 ib XOR r/m32,imm8 2/7 XOR sign-extended immediate byte
with r/m dword
30 /r XOR r/m8,r8 2/6 Exclusive-OR byte register to r/m
byte
31 /r XOR r/m16,r16 2/6 Exclusive-OR word register to r/m
word
31 /r XOR r/m32,r32 2/6 Exclusive-OR dword register to r/m
dword
32 /r XOR r8,r/m8 2/7 Exclusive-OR byte register to r/m
byte
33 /r XOR r16,r/m16 2/7 Exclusive-OR word register to r/m
word
33 /r XOR r32,r/m32 2/7 Exclusive-OR dword register to r/m
dword
Operation
DEST  LeftSRC XOR RightSRC
CF  0
OF  0
Description
XOR computes the exclusive OR of the two operands. Each bit of the result
is 1 if the corresponding bits of the operands are different; each bit is 0
if the corresponding bits are the same. The answer replaces the first
operand.
Flags Affected
CF = 0, OF = 0; SF, ZF, and PF as described in Appendix C; AF is undefined
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page
fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault