mirror of
				https://github.com/larsbrinkhoff/awesome-cpus
				synced 2025-11-04 10:16:01 +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 |