mirror of
https://github.com/larsbrinkhoff/awesome-cpus
synced 2025-04-16 10:04:37 +03:00
9919 lines
351 KiB
Plaintext
9919 lines
351 KiB
Plaintext
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 |