			 PART IV  INSTRUCTION SET                          

The exact descriptions of each instruction in here are probably a big
portion of what INTeL's competitors used to knock off the 386. They are
also the real descriptions of the machines modes and so on. I stuck the
ASCII-related legacy instructions at the end of part 5. 


Chapter 17  80386 Instruction Set

Throughout the INTeL version of this section quad and dual versions of
opcodes are considered distinct instructions. They are usually identical
except for the state of the USE32 bit in CS, and possibly some size-change
prefixes. THe dword forms have been removed in most cases. "word" usually
means cell, i.e. dual or quad depending on system state, if I haven't
changed it to "cell".. r16 and so on imply r16 or r32. The timings will be
the same in most cases also. Transfers that can have numerous forms based
on gates used and so on have been reduced to the basic variations. Just
know that task-switches take about 300 clocks, pmode takes longer than
rmode for control transfers, and so on. If you bought into task gates and
the TSS and all that you probably don't want to know the 386 clocks
ratings anyway :o)


............................................................................

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 either
dual or quad operands 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. The basic switch for
operand and address sizes is the D-bit in the active CS segment
descriptor. 1 is quads, 0 is duals. This is independant of the PE bit
which causes memory protection to be enforced.


17.1.1  Default Segment Attribute

For programs executed in protected mode, the D-bit in executable-segment
descriptors (under CS) 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  A  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
 SP 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

      r---------------t---------------t---------------t---------------L
      |  INSTRUCTION  |   ADDRESS-    |    OPERAND-   |   SEGMENT     |
      |    PREFIX     |  SIZE PREFIX  |  SIZE PREFIX  |   OVERRIDE    |
      |---------------+---------------+---------------+---------------|
      |     0 OR 1         0 OR 1           0 OR 1         0 OR 1     |
      L. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .|
      |                        NUMBER OF BYTES                        |
      `---------------------------------------------------------------'

      r----------t-----------t-------t------------------t-------------L
      |  OPCODE  |  MODR/M   |  SIB  |   DISPLACEMENT   |  IMM DIATE  |
      |          |           |       |                  |             |
      |----------+-----------+-------+------------------+-------------|
      |  1 OR 2     0 OR 1    0 OR 1      0,1,2 OR 4       0,1,2 OR 4 |
      L. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .|
      |                        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
		    r--------t-------------t-------------t
		    |  MOD   | REG/OPCODE  |     R/M     |
		    `--------+-------------+-------------'

			  SIB (SCALE INDEX BASE) BYTE

		     7    6    5    4    3    2    1    0
		    r--------t-------------t-------------t
		    |   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)                     A     C     D     B     SP    BP    SI    DI
/digit (Opcode)            0     1     2     3     4     5     6     7
REG =                      000   001   010   011   100   101   110   111

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

Effective
Address ......../
		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

 A /AX/AL            000   C0    C8    D0    D8    E0    E8    F0    F8
 C /CX/CL            001   C1    C9    D1    D9    E1    E9    F1    F9
 D /DX/DL            010   C2    CA    D2    DA    E2    EA    F2    FA
 B /BX/BL            011   C3    CB    D3    DB    E3    EB    F3    FB
 SP/SP/AH        11  100   C4    CC    D4    DC    E4    EC    F4    FC
 BP/BP/CH            101   C5    CD    D5    DD    E5    ED    F5    FD
 SI/SI/DH            110   C6    CE    D6    DE    E6    EE    F6    FE
 DI/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)                     A     C     D     B     SP    BP    SI    DI
/digit (Opcode)            0     1     2     3     4     5     6     7
REG =                      000   001   010   011   100   101   110   111


Effective
Address
/...       ..\ 
	     \Mod R/M/  
		     /.........ModR/M Values in Hexadecimal ...........\

[ A ]                000   00    08    10    18    20    28    30    38
[ C ]                001   01    09    11    19    21    29    31    39
[ D ]                010   02    0A    12    1A    22    2A    32    3A
[ B ]                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
[ SI]                110   06    0E    16    1E    26    2E    36    3E
[ DI]                111   07    0F    17    1F    27    2F    37    3F

disp8[ A ]           000   40    48    50    58    60    68    70    78
disp8[ C ]           001   41    49    51    59    61    69    71    79
disp8[ D ]           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[ SI]           110   46    4E    56    5E    66    6E    76    7E
disp8[ DI]           111   47    4F    57    5F    67    6F    77    7F

disp32[ A ]          000   80    88    90    98    A0    A8    B0    B8
disp32[ C ]          001   81    89    91    99    A1    A9    B1    B9
disp32[ D ]          010   82    8A    92    9A    A2    AA    B2    BA
disp32[ B ]          011   83    8B    93    9B    A3    AB    B3    BB
disp32[--] [--]  10  100   84    8C    94    9C    A4    AC    B4    BC
disp32[ BP]          101   85    8D    95    9D    A5    AD    B5    BD
disp32[ SI]          110   86    8E    96    9E    A6    AE    B6    BE
disp32[ DI]          111   87    8F    97    9F    A7    AF    B7    BF

 A /AX/AL            000   C0    C8    D0    D8    E0    E8    F0    F8
 C /CX/CL            001   C1    C9    D1    D9    E1    E9    F1    F9
 D /DX/DL            010   C2    CA    D2    DA    E2    EA    F2    FA
 B /BX/BL            011   C3    CB    D3    DB    E3    EB    F3    FB
 SP/SP/AH        11  100   C4    CC    D4    DC    E4    EC    F4    FC
 BP/BP/CH            101   C5    CD    D5    DD    E5    ED    F5    FD
 SI/SI/DH            110   C6    CE    D6    DE    E6    EE    F6    FE
 DI/DI/BH            111   C7    CF    D7    DF    E7    EF    F7    FF


[--] [--] 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.


...........................................................................
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                       A     C     D     B     SP   [*]
[*] means a disp32 with no base if MOD is 00, [ SP] otherwise. This provides
the following addressing modes:
      disp32[index]        (MOD=00)
      disp8[ BP][index]    (MOD=01)
      disp32[ BP][index]   (MOD=10)   SI    DI
   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, [ SP] otherwise. This provides
the following addressing modes:
      disp32[index]        (MOD=00)
      disp8[ BP][index]    (MOD=01)
      disp32[ BP][index]   (MOD=10)()SS Index(  


		     /........ModR/M Values in Hexadecimal............../

[ A ]                000    00    01    02    03    04    05    06    07
[ C ]                001    08    09    0A    0B    0C    0D    0E    0F
[ D ]                010    10    11    12    13    14    15    16    17
[ B ]                011    18    19    1A    1B    1C    1D    1E    1F
none             00  100    20    21    22    23    24    25    26    27
[ BP]                101    28    29    2A    2B    2C    2D    2E    2F
[ SI]                110    30    31    32    33    34    35    36    37
[ DI]                111    38    39    3A    3B    3C    3D    3E    3F

[ A *2]              000    40    41    42    43    44    45    46    47
[ C *2]              001    48    49    4A    4B    4C    4D    4E    4F
[ C *2]              010    50    51    52    53    54    55    56    57
[ B *2]              011    58    59    5A    5B    5C    5D    5E    5F
none             01  100    60    61    62    63    64    65    66    67
[ BP*2]              101    68    69    6A    6B    6C    6D    6E    6F
[ SI*2]              110    70    71    72    73    74    75    76    77
[ DI*2]              111    78    79    7A    7B    7C    7D    7E    7F

[ A *4]              000    80    81    82    83    84    85    86    87
[ C *4]              001    88    89    8A    8B    8C    8D    8E    8F
[ D *4]              010    90    91    92    93    94    95    96    97
[ B *4]              011    98    89    9A    9B    9C    9D    9E    9F
none             10  100    A0    A1    A2    A3    A4    A5    A6    A7
[ BP*4]              101    A8    A9    AA    AB    AC    AD    AE    AF
[ SI*4]              110    B0    B1    B2    B3    B4    B5    B6    B7
[ DI*4]              111    B8    B9    BA    BB    BC    BD    BE    BF

[ A *8]              000    C0    C1    C2    C3    C4    C5    C6    C7
[ C *8]              001    C8    C9    CA    CB    CC    CD    CE    CF
[ D *8]              010    D0    D1    D2    D3    D4    D5    D6    D7
[ B *8]              011    D8    D9    DA    DB    DC    DD    DE    DF
none             11  100    E0    E1    E2    E3    E4    E5    E6    E7
[ BP*8]              101    E8    E9    EA    EB    EC    ED    EE    EF
[ SI*8]              110    F0    F1    F2    F3    F4    F5    F6    F7
[ DI*8]              111    F8    F9    FA    FB    FC    FD    FE    FF


...........................................................................
NOTES:
  [*] means a disp32 with no base if MOD is 00, [ SP] otherwise. This
  provides the following addressing modes:
      disp32[index]        (MOD=00)
      disp8[ BP][index]    (MOD=01)
      disp32[ BP][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      A  = 0
    CL = 1     CX = 1      C  = 1
    DL = 2     DX = 2      D  = 2
    BL = 3     BX = 3      B  = 3
    AH = 4     SP = 4      SP = 4
    CH = 5     BP = 5      BP = 5
    DH = 6     SI = 6      SI = 6
    BH = 7     DI = 7      DI = 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  A ,  C ,  D ,  B ,  SP,  BP,  SI, or
 DI.

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:  A ,  B ,
 C ,  D ,  SP,  BP,  SI,  DI. 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  SP 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
	  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;
   FI;

  !  Pop(value) removes the value from the top of the stack and returns it.
     The statement  A  <! Pop( ); assigns to  A  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:[ SP]; (* 2 bytes value *)
	  SP <!  SP + 2;
      ELSE (* OperandSize = 32 *)
	 ret val <! SS:[ SP]; (* 4 bytes value *)
	  SP <!  SP + 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[ A , 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[ A , 21]

   31                    21                                              0
  r---------------------t-t-----------------------------------------------t
  |                     | |                                               |
  `---------------------+-+-----------------------------------------------'

			 ^                                                ^
			 L....................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
	     r----,-,---------,---------------,----------------t
	     |    l l         l               l                |
	     `----L-L---------L---------------|----------------'
	     l  BITBASE + 1   l    BITBASE    l  BITBASE - 1   l
		   !                          l
		   L........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
	     r----------------,---------------,---,-,----------L
	     |                l               l   l l          |
	     `----------------|---------------L---L-L----------'
	     l    BITBASE     l  BITBASE - 1  l  BITBASE - 2   l
			      l                    !
			      L.....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.



ADC .. Add with Carry


Opcode    Instruction      Clocks    Description

14 ib     ADC AL,imm8      2         Add with carry immediate byte to AL
15 iw     ADC A,imm16	   2         Add with carry immediate word to AX
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
83 /2 ib  ADC r/m16,imm8   2/7       Add with CF sign-extended immediate
				     byte to r/m word
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
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


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 cell to AX
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 cell to r/m cell
83 /0 ib  ADD r/m16,imm8       2/7      Add sign-extended immediate byte
					to r/m cell
00 /r     ADD r/m8,r8          2/7      Add byte register to r/m byte
01 /r     ADD r/m16,r16        2/7      Add cell register to r/m cell
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 cell to cell 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 ic     AND AX,imm16         2         AND immediate cell to AX
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
83 /4 ib  AND r/m16,imm8       2/7       AND sign-extended immediate byte
					 with r/m word
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
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


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


ARRL .. Adjust RRL Field of Selector

Opcode    Instruction          Clocks    Description

63 /r     ARRL r/m16,r16       pm=20/21  Adjust RRL of r/m16 to not
					 less than RRL of r16


Operation

IF RRL bits(0,1) of DEST <! RRL bits(0,1) of SRC
THEN
   ZF <! 1;
   RRL bits(0,1) of DEST <! RRL bits(0,1) of SRC;
ELSE
   ZF <! 0;
FI;

Description

The ARRL 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 RRL field ("requested restriction
level"..bottom two bits) of the first operand is less than the RRL field of
the second operand, the zero flag is set to 1 and the RRL 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.

ARRL appears in operating system software, not in application programs. It
is used to guarantee that a selector parameter to a subroutine does not
request less restriction than the caller is allowed. The second operand of
ARRL 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; ARRL 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)


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


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


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  BA /4 ib   BT r/m16,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 core 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  BA /7 ib  BTC r/m16,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 core 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  BA /6 ib  BTR r/m16,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 core 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  BA /5 ib  BTS r/m16,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 core 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


E8  cw    CALL rel16       7+m            Call near, displacement relative
					  to next instruction
9A  cd    CALL ptr16:16    17+m,pm=34+m   Call intersegment, to full
					  pointer given
FF  /2    CALL r/m16       7+m/10+m       Call near, register
					  indirect/memory indirect
FF  /3    CALL m16:16      22+m,pm=38+m   Call intersegment, address at
					  r/m dword



...........................................................................

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:
   DRL must be <= CRL 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:
   RRL must be <= CRL ELSE #GP(code segment selector)
   DRL must be = CRL 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 RRL of CS to CRL
   Load EIP with zero-extend(new offset);
   IF OperandSize=16 THEN EIP <! EIP AND 0000FFFFH; FI;

CALL-GATE:
   Call gate DRL must be >= CRL ELSE #GP(call gate selector)
   Call gate DRL must be >= RRL 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)
   DRL of selected descriptor must be <= CRL ELSE
      #GP(code segment selector)
   IF non-conforming code segment AND DRL < CRL
   THEN go to less-restriction
   ELSE go to SAME-restriction
   FI;

less-restriction:
   Get new SS selector for new restriction 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 RRL must equal DRL of code segment
	    ELSE #TS(SS selector)
	 Stack segment DRL must equal DRL 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 CRL to stack segment DRL
      Set RRL of CS to CRL

SAME-restriction:
   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 RRL of CS to CRL

TASK-GATE:
   Task gate DRL must be >= CRL ELSE #TS(gate selector)
   Task gate DRL must be >= RRL 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 DRL must be >= CRL else #TS(TSS selector)
   TSS DRL must be >= RRL 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


Operation

IF OperandSize = 16 (* instruction = CBW *)
THEN AX <! SignExtend(AL);
ELSE (* OperandSize = 32, instruction = CWDE *)
    A  <! 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  A  by extending the most
significant bit of AX into the two most significant bytes of  A . Note that
CWDE is different from CWD. CWD uses DX:AX rather than  A  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 restriction level is at least as
privileged as IORL. 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 restriction level is greater than the IORL in the
flags register. IORL specifies the most restricted 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 restricted instruction that can only be executed at restriction 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 restriction 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

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
83  /7 ib       CMP r/m16,imm8     2/5      Compare sign extended immediate
					    byte to r/m word
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
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
3C  ib          CMP AL,imm8        2        Compare immediate byte to AL
3D  iw          CMP AX,imm16       2        Compare immediate word to AX


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)


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  SI for source-index and  DI 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  SI and
 DI will be used. Load the correct index values into SI and DI (or  SI and
 DI) 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
[ SI] - [ DI]. The left operand (SI or  SI) is the source and the right
operand (DI or  DI) 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  SI), the DS register
is used, unless a segment override byte is present. The second operand (DI
or  DI) 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  C  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         D : A  <! sign-extend of  A 


Operation

IF OperandSize = 16 (* CWD instruction *)
THEN
   IF AX <! 0 THEN DX <! 0FFFFH; ELSE DX <! 0; FI;
ELSE (* OperandSize = 32, CDQ instruction *)
   IF  A  <! 0 THEN  D  <! 0FFFFFFFFH; ELSE  D  <! 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  A  to a signed 64-bit integer in the
register pair  D : A  by extending the most significant bit of  A 
(the sign bit) into all the bits of  D . Note that CWD is different from
CWDE. CWDE uses  A  as a destination, instead of DX:AX.

Flags Affected

None

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


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)


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    D : A       r/m32       A           D 

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  A ), 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  A ), 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 ( BP) 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 *)
	  BP <!  BP - 4;
	 Push[ BP];
      FI;
   OD;
   Push(frame-ptr)
FI;
IF OperandSize = 16 THEN BP <! frame-ptr ELSE  BP <! frame-ptr; FI;
IF StackAddrSize = 16
THEN SP <! SP - First operand;
ELSE  SP <!  SP - 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  BP, 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  BP for the frame pointer and  SP for the stack
pointer.

If the second operand is 0, ENTER pushes the frame pointer (BP or
 BP) 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  SP 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 restricted instruction; #GP(0) if the current restriction level is
not 0

Real Address Mode Exceptions

None

Virtual 8086 Mode Exceptions

#GP(0); HLT is a restricted 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)


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        A            D        D : A 

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
0F  AF /r   IMUL r16,r/m16         9-22/12-25  word register <! word
					       register * r/m word
6B  /r ib   IMUL r16,r/m16,imm8    9-14/12-17  word register <! r/m16 *
					       sign-extended immediate byte
69  /r iw   IMUL r16,r/m16,imm16   9-22/12-25  word register <! r/m16 *
					       immediate word

...........................................................................
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} lml), 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                D : A  = sign-extend of  A  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
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


...........................................................................
NOTES:
   *If CRL <= IORL
  **If CRL > IORL or if in virtual 8086 mode
...........................................................................

Operation

IF (PE = 1) AND ((VM = 1) OR (CRL > IORL))
THEN (* Virtual 8086 mode, or protected mode with CRL > IORL *)
   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  A ) 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 restriction level is larger than IORL 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 cell by 1
40 + rw     INC r16                        Increment core 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      INSW r/m16,DX   15,pm=9*/29**  Input cell from port DX into ES:(E)DI


...........................................................................
NOTES:
   *If CRL <= IORL
  **If CRL > IORL or if in virtual 8086 mode
...........................................................................

Operation

IF AddressSize = 16
THEN use DI for dest-index;
ELSE (* AddressSize = 32 *)
   use  DI for dest-index;
FI;
IF (PE = 1) AND ((VM = 1) OR (CRL > IORL))
THEN (* Virtual 8086 mode, or protected mode with CRL > IORL *)
   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 cell at ES:dest-index. The memory operand must
be addressable from ES; no segment override is possible. The destination
register is DI.

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. 386 IO-space
is limited to the size of DX, 16 bits, 64k.

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 DI advances automatically. If the
direction flag is 0 (CLD was executed), DI or DI increments; if the
direction flag is 1 (STD was executed), DI or DI decrements. DI increments
or decrements by 1 if a byte is input or by cell size, 2 or 4.

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 cells. This is how it differs from IN. Refer to the REP
instruction for details of this operation.

Flags Affected

None

Protected Mode Exceptions

#GP(0) if CRL is numerically greater than IORL 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
CD ib     INT imm8     37              Interrupt numbered by immediate
				       byte
CE        INTO         Fail:3,pm=3;
		       Pass:35         Interrupt 4--if overflow flag is 1


...........................................................................
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 DRL < CRL
      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 DRL < CRL
   THEN GOTO INTERRUPT-TO-INNER-restriction;
   ELSE
      IF code segment is conforming OR code segment DRL = CRL
      THEN GOTO INTERRUPT-TO-SAME-restriction-LEVEL;
      ELSE #GP(CS selector + EXT);
      FI;
   FI;

INTERRUPT-TO-INNER-restriction:
   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 RRL must equal DRL of code segment, else #TS(SS
	 selector+EXT);
      Stack segment DRL must equal DRL 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 duals padded to 4 *);
      Push (EFLAGS);
      Push (long pointer to return location) (* 3 duals padded to 4*);
   ELSE
      Push (long pointer to old stack) (* 2 duals *);
      Push (FLAGS);
      Push (long pointer to return location) (* 2 duals *);
   FI;
   Set CRL to new code segment DRL;
   Set RRL of CS to CRL;
   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;
   Temp SP <!  SP;
   SS <! TSS.SS0; (* Change to level 0 stack segment *)
    SP <! TSS. SP0; (* 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(Temp SP);
   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-restriction-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 RRL field of CS to CRL;
   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  SP = 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 IORL 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)

...........................................................................
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 RRL < > 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 DRL 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 RRL not = RRL 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 DRL not = RRL 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.RRL > CRL
   THEN
      Temp SP <! Pop();
      TempSS <! Pop();
      SS: SP <! TempSS:Temp SP;
   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 RRL must be >= CRL, else #GP(Return selector);
   IF return selector RRL = CRL
   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 DRL must = CRL;
   ELSE #GP(Return selector);
   FI;
   IF conforming
   THEN code segment DRL must be <= CRL, 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 DRL must = CS selector RRL;
      ELSE #GP(Return selector);
      FI;
      IF conforming
      THEN code segment DRL must be > CRL;
      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 RRL must equal the RRL of the return CS selector
	 ELSE #GP(SS selector);
      AR byte must indicate a writable data segment, else #GP(SS selector);
      Stack segment DRL must equal the RRL 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 CRL to the RRL 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 DRL must be >= CRL, or DRL must be >= RRL;
   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 IORL bits in the flag register are changed
only when CRL equals 0.

If NT equals 0, IRET returns from an interrupt procedure without a
task switch. The code returned to must be equally or more restricted than
the interrupt routine (as indicated by the RRL bits of the CS selector
popped from the stack). If the destination code is more restricted, 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 IORL is less than 3, to permit emulation


Jcc .. Jump if Condition is Met

Opcode         Instruction       Clocks   Description

					jump short relative if...
70  cb         JO rel8           7+m,3		(OF=1)
71  cb         JNO rel8          7+m,3		(OF=0)
72  cb         JB rel8           7+m,3		(CF=1)
73  cb         JAE rel8          7+m,3		(CF=0)
74  cb         JE rel8           7+m,3		(ZF=1)
75  cb         JNE rel8          7+m,3		(ZF=0)
76  cb         JBE rel8          7+m,3		(CF=1 or ZF=1)
77  cb         JA rel8           7+m,3		(CF=0 and ZF=0)
78  cb         JS rel8           7+m,3		(SF=1)
79  cb         JNS rel8          7+m,3		(SF=0)
7A  cb         JPE rel8          7+m,3		(PF=1)
7B  cb         JNP rel8          7+m,3		(PF=0)
7C  cb         JL rel8           7+m,3		(SF<>OF)
7D  cb         JGE rel8          7+m,3		(SF=OF)
7E  cb         JLE rel8          7+m,3		(ZF=1 and SF<>OF)
7F  cb         JG rel8           7+m,3		(ZF=0 and SF=OF)

					jump relative if...
0F  80 cw/cd   JO rel16/32       7+m,3		(OF=1)
0F  81 cw/cd   JNO rel16/32      7+m,3		(OF=0)
0F  82 cw/cd   JB rel16/32       7+m,3		(CF=1)
0F  83 cw/cd   JAE rel16/32      7+m,3		(CF=0)
0F  84 cw/cd   JE rel16/32       7+m,3		(ZF=1)
0F  85 cw/cd   JNE rel16/32      7+m,3		(ZF=0)
0F  86 cw/cd   JBE rel16/32      7+m,3		(CF=1 or ZF=1)
0F  87 cw/cd   JA rel16/32       7+m,3		(CF=0 and ZF=0)
0F  88 cw/cd   JS rel16/32       7+m,3		(SF=1)
0F  89 cw/cd   JNS rel16/32      7+m,3		(SF=0)
0F  8A cw/cd   JPE rel16/32      7+m,3		(PF=1)
0F  8B cw/cd   JPO rel16/32      7+m,3		(PF=0)
0F  8C cw/cd   JL rel16/32       7+m,3		(SF<>OF)
0F  8D cw/cd   JGE rel16/32      7+m,3		(SF=OF)
0F  8E cw/cd   JLE rel16/32      7+m,3		(ZF=1 and SF<>OF)
0F  8F cw/cd   JG rel16/32       7+m,3		(ZF=0 and SF=OF)

E3  cb         JCXZ rel8         9+m,5    Jump short if CX register is 0

...........................................................................
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:

JCXZ differs from other conditional jumps because it tests the contents of
the CX or  C  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
 C  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

E9  cw    JMP rel16       7+m             Jump near, displacement relative
					  to next instruction
EB  cb    JMP rel8        7+m             Jump short
EA  cd    JMP ptr16:16    12+m,pm=27+m    Jump intersegment, 4-byte
					  immediate address
FF  /4    JMP r/m16       7+m/10+m        Jump near indirect
FF  /5    JMP m16:16      43+m,pm=31+m    Jump r/m16:16 indirect and
					  intersegment

...........................................................................
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 DRL must be <= CRL 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:
   RRL of destination selector must be <= CRL ELSE #GP(selector);
   Descriptor DRL must be = CRL 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 RRL field of CS register to CRL;

CALL-GATE:
   Descriptor DRL must be >= CRL ELSE #GP(gate selector);
   Descriptor DRL must be >= gate selector RRL 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, DRL must = CRL
      ELSE #GP(CS selector);
      FI;
      IF conforming
      THEN code-segment descriptor DRL must be <= CRL;
      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 RRL of CS to CRL

TASK-GATE:
   Gate descriptor DRL must be >= CRL ELSE #GP(gate selector);
   Gate descriptor DRL must be >= gate selector RRL 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 DRL must be >= CRL ELSE #GP(TSS selector);
   TSS DRL must be >= TSS selector RRL 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 restriction 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


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
CRL (modified by the selector's RRL) 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

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


Operation

IF StackAddrSize = 16
THEN
   SP <! BP;
ELSE (* StackAddrSize = 32 *)
    SP <!  BP;
FI;
IF OperandSize = 16
THEN
   BP <! Pop();
ELSE (* OperandSize = 32 *)
    BP <! 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  BP, 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 restriction 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

C4  /r      LES r16,m16:16   7,p=22   Load ES:r16 with pointer from memory
C5  /r      LDS r16,m16:16   7,p=22   Load DS:r16 with pointer from memory
0F  B2 /r   LSS r16,m16:16   7,p=22   Load SS:r16 with pointer from memory
0F  B4 /r   LFS r16,m16:16   7,p=25   Load FS:r16 with pointer from memory
0F  B5 /r   LGS r16,m16:16   7,p=25   Load GS:r16 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 RRL must equal CRL ELSE #GP(selector);
   AR byte must indicate a writable data segment ELSE #GP(selector);
   DRL in the AR byte must equal CRL 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 RRL and the CRL must be less than or equal to DRL in
      AR byte;
   ELSE #GP(selector);
   Segment must be marked present ELSE #NP(selector);
Load segment register with selector and RRL 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 restriction 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 restriction 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


Operation

IF AddressSize = 16
THEN use SI for source-index
ELSE (* AddressSize = 32 *)
   use  SI 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 *)
       A  <! [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  A  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  SI register is used. The address of the source data is
determined solely by the contents of  SI/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
 A , 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
E0  cb   LOOPNE rel8  11+m    DEC count; jump short if count <> 0 and ZF=0


Operation

IF AddressSize = 16 THEN CountReg is CX ELSE CountReg is  C ; 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  C  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)

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 CRL
weakened by RRL, 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 restriction 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
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
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
A2       MOV moffs8,AL     2             Move AL to (seg:offset)
A3       MOV moffs16,AX    2             Move AX 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
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


...........................................................................
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 RRL must equal CRL else #GP(selector);
AR byte must indicate a writable data segment else #GP(selector);
   DRL in the AR byte must equal CRL 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 RRL and the CRL must be less than or equal to DRL 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  21 /r   MOV r32,DR0 -- 3      22       Move (debug register) to
					   (register)
0F  22 /r   MOV CR0/CR2/CR3,r32   10/4/5   Move (register) to (control
					   register)
0F  23 /r   MOV DR0 -- 3,r32      22       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 restriction 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 restriction 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 core 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]


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  SI for source-index and  DI 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

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

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)


...........................................................................
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} lml), 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 *)
       D : A  <!  A  * 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  A  and the result is left in
      D : A .  D  contains the high-order 32 bits of the product. The
     carry and overflow flags are set to 0 if  D  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


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 cell


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

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
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
0C  ib       OR AL,imm8        2         OR immediate byte to AL
0D  iw       OR AX,imm16       2         OR immediate word to AX
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
83  /1 ib    OR r/m16,imm8     2/7       OR sign-extended immediate byte
					 with r/m word


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
EE        OUT DX,AL       11,pm=5*/25**   Output byte AL to port number inDX
EF        OUT DX,AX       11,pm=5*/25**   Output word AL to port number inDX


...........................................................................
NOTES:
   *If CRL <= IORL
  **If CRL > IORL or if in virtual 8086 mode
...........................................................................

Operation

IF (PE = 1) AND ((VM = 1) OR (CRL > IORL))
THEN (* Virtual 8086 mode, or protected mode with CRL > IORL *)
   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
 A ) 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 restriction level is higher (has more restriction) than
IORL 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


...........................................................................
NOTES:
   *If CRL <= IORL
  **If CRL > IORL or if in virtual 8086 mode
...........................................................................

Operation

IF AddressSize = 16
THEN use SI for source-index;
ELSE (* AddressSize = 32 *)
   use  SI for source-index;
FI;

IF (PE = 1) AND ((VM = 1) OR (CRL > IORL))
THEN (* Virtual 8086 mode, or protected mode with CRL > IORL *)
   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  SI 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  SI 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 CRL is greater than IORL 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

07          POP ES        7,pm=21    Pop top of stack into ES
0F   A1     POP FS        7,pm=21    Pop top of stack into FS
17          POP SS        7,pm=21    Pop top of stack into SS
1F          POP DS        7,pm=21    Pop top of stack into DS
58 + rw     POP r16       4          Pop top of stack into word register
8F   /0     POP m16       5          Pop top of stack into memory word


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: SP); (* copy a word *)
       SP <!  SP + 2;
   ELSE (* OperandSize = 32 *)
      DEST <! (SS: SP); (* copy a dword *)
       SP <!  SP + 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: SP
(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 RRL must equal CRL ELSE #GP(selector);
   AR byte must indicate a writable data segment ELSE #GP(selector);
   DRL in the AR byte must equal CRL 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 RRL and the CRL must be less than or equal to DRL 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 Core Registers		( pullcore in osimplay)

Opcode   Instruction   Clocks   Description

61       POPAD         24       Pop  DI,  SI,  BP,  SP,  D ,  C , and  A 


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 *)
    DI <! Pop();
    SI <! Pop();
    BP <! Pop();
   throwaway <! Pop (); (* Skip  SP *)
    B  <! Pop();
    D  <! Pop();
    C  <! Pop();
    A  <! Pop();
FI;

Description

POPA pops the eight core registers at the current cell size. However, the
SP value is discarded instead of loaded into SP. POPA reverses a previous
PUSHA, restoring the core registers to their values before PUSHA was
executed. The first register popped is DI, which POPA (pullcore)
presumably left at TOS.

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       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 restriction level is altered only when executing at restriction level
0. The interrupt flag is altered only when executing at a level at least as
privileged as the I/O restriction level. (Real-address mode is equivalent to
restriction 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 IORL is less than 3, to permit emulation


PUSH .. Push Operand onto the Stack

Opcode     Instruction   Clocks   Description

06         PUSH ES       2        Push ES
0E         PUSH CS       2        Push CS
0F   A0    PUSH FS       2        Push FS
16         PUSH SS       2        Push SS
1E         PUSH DS       2        Push DS
50 + /r    PUSH r16      2        Push register word
6A         PUSH imm8     2        Push immediate byte
68         PUSH imm16    2        Push immediate word
FF   /6    PUSH m16      5        Push memory word


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
       SP <!  SP - 2;
      (SS: SP) <! (SOURCE); (* word assignment *)
   ELSE
       SP <!  SP - 4;
      (SS: SP) <! (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  SP 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  SP 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 .. Push all Core Registers		(pushcore in osimplay)

Opcode  Instruction  Clocks   Description

60      PUSHA        18       Push  A ,  C ,  D ,  B , original  SP,  BP,
			       SI, and  DI


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 <! ( SP);
   Push( A );
   Push( C );
   Push( D );
   Push( B );
   Push(Temp);
   Push( BP);
   Push( SI);
   Push( DI);
FI;

Description

PUSHA pushes all core registers onto the 80386 stack at the current cell
size with appropriate subtraction from SP, subtracting since the 386 stack
grows toward lower memory addresses. 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,m
whichb is then at TOS, "Top" of Stack.

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
 SP equals 1, 3, or 5; if SP or  SP 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      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 IORL is less than 3, to permit emulation


RCL/RCR/ROL/ROR .. Rotate


Opcode       Instruction       Clocks  Description

C0  /0 ib    ROL r/m8,imm8     3/7     Rotate 8 bits r/m byte left imm8 times
C0  /1 ib    ROR r/m8,imm8     3/7     Rotate 8 bits r/m word right imm8
				       times
C0  /2 ib    RCL r/m8,imm8     9/10    Rotate 9 bits (CF,r/m byte) left
				       imm8 times
C0  /3 ib    RCR r/m8,imm8     9/10    Rotate 9 bits (CF,r/m byte) right
				       imm8 times

C1  /0 ib    ROL r/m16,imm8    3/7     Rotate 16 bits r/m word left imm8 times
C1  /1 ib    ROR r/m32,imm8    3/7     Rotate 32 bits r/m dword right imm8
				        times
C1  /2 ib    RCL r/m16,imm8    9/10    Rotate 17 bits (CF,r/m word) left
				        imm8 times
C1  /3 ib    RCR r/m16,imm8    9/10    Rotate 17 bits (CF,r/m word) right
				        imm8 times

D0  /0       ROL r/m8,1        3/7     Rotate 8 bits r/m byte left once
D0  /1       ROR r/m8,1        3/7     Rotate 8 bits r/m byte right once
D0  /2       RCL r/m8,1        9/10    Rotate 9 bits (CF,r/m byte) left once
D0  /3       RCR r/m8,1        9/10    Rotate 9 bits (CF,r/m byte) right once

D1  /0       ROL r/m16,1       3/7     Rotate 16 bits r/m word left once
D1  /1       ROR r/m16,1       3/7     Rotate 16 bits r/m word right once
D1  /2       RCL r/m16,1       9/10    Rotate 17 bits (CF,r/m word) left once
D1  /3       RCR r/m16,1       9/10    Rotate 17 bits (CF,r/m word) right once

D2  /0       ROL r/m8,CL       3/7     Rotate 8 bits r/m byte left CL  times
D2  /1       ROR r/m8,CL       3/7     Rotate 8 bits r/m byte right CL  times
D2  /2       RCL r/m8,CL       9/10    Rotate 9 bits (CF,r/m byte) left CL times
D2  /3       RCR r/m8,CL       9/10    Rotate 9 bits (CF,r/m byte) right CL 
					times

D3  /0       ROL r/m32,CL      3/7     Rotate 32 bits r/m dword left CL times
D3  /1       ROR r/m16,CL      3/7     Rotate 16 bits r/m word right CL times
D3  /2       RCL r/m16,CL      9/10    Rotate 17 bits (CF,r/m word) left CL 
     					times
D3  /3       RCR r/m16,CL      9/10    Rotate 17 bits (CF,r/m word) right
				        CL 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

The REP prefixes are not like segment or size-change prefixes in that they
are tied to certain instructions and do form a compound thing, mostly with
string operations, which is why they are called string operations. Thus
the possible combinations are listed by INTeL explicitly. INS alone takes
more clocks than one iteration of it in a REP operation. As with most
instructions, there is a distinct opcode for the bytewise form and the
cellwise form. REPE is the same binary opcode as REP, but the name
reflects its different loop-escape behavior in conjunction with SCAS and
CMPs, in which cases it considers the ZF after the string primitive
operation, as well as the count in C.


Opcode    Instruction         Clocks           Description

F2  A7    REPNE CMPS m16,m16  5+9*N            Find matching words 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
----
F3  6C    REP INS r/m8, DX    13+6*(E)CX,
			      pm=7+6*(E)CX	If CRL <= IORL/
			      27+6*(E)CX	If CRL > IORL 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 CRL <= IORL/
			      27+6*(E)CX	If CRL > IORL or if in 
							virtual 8086 mode      
						Input (E)CX words from port
					       DX into ES:[(E)DI]
F3  6E    REP OUTS DX,r/m8    5+12*(E)CX,
			      pm=6+5*(E)CX	If CRL <= IORL/
			      26+5*(E)CX	If CRL > IORL 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 CRL <= IORL/
			      26+5*(E)CX	If CRL > IORL or if in 
							virtual 8086 mode      
						Output (E)CX words from
					       [(E)SI] to port DX 
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  A6    REP CMPS m8,m8     5+9*N            Find nonmatching bytes in
					       ES:[(E)DI] and [(E)SI]
F3  A7    REP CMPS m16,m16   5+9*N            Find nonmatching words in
					       ES:[(E)DI] and [(E)SI]
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  AE    REP SCAS m8        5+8*N            Find non-AL byte starting
					       at ES:[(E)DI]
F3  AF    REP SCAS m16       5+8*N            Find non-AX word starting
					       at ES:[(E)DI]


Operation

IF AddressSize = 16
THEN use CX for CountReg;
ELSE (* AddressSize = 32 *) use  C  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 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  C  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  C  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

C2  iw     RET imm16    10+m           Return (near), pop imm16 bytes of
					       parameters
			18+m,pm=32+m   Return (far), same restriction, pop
					       imm16 bytes
C3         RET          10+m           Return (near) to caller
CB         RET          18+m,pm=32+m   Return (far) to caller, same
				        restriction
			pm=68          Return (far), more restriction,
				        switch stacks


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 RRL must be >= CRL ELSE #GP(return selector)
   IF return selector RRL = CRL
   THEN GOTO SAME-LEVEL;
   ELSE GOTO OUTER-restriction-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 DRL must equal CRL;
   ELSE #GP(selector);
   FI;
   IF conforming
   THEN code segment DRL must be <= CRL;
   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-restriction-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 DRL must equal return selector RRL
      ELSE #GP(selector);
      FI;
      IF conforming
      THEN code segment DRL must be <= return selector RRL;
      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 RRL must equal the RRL of the return CS selector ELSE
	 #GP(selector);
      Descriptor AR byte must indicate a writable data segment ELSE
	 #GP(selector);
      Descriptor DRL must equal the RRL 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 CRL to the RRL of the return CS selector;
   IF OperandMode=32
   THEN
      Load CS:EIP from stack;
      Set CS RRL to CRL;
      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 RRL to CRL;
      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
	    DRL must be >= CRL, or DRL must be >= RRL;
      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 greater restriction than the current restriction
level. Returns to a greater restriction 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 restriction level, they are set to
0 to prevent unauthorized access from the new restriction 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

C0   /4 ib      SAL r/m8,imm8     3/7     Multiply r/m byte by 2, imm8
C0   /5 ib      SHR r/m8,imm8     3/7     Unsigned divide r/m byte by 2,
					  imm8 times
C0   /7 ib      SAR r/m8,imm8     3/7     Signed divide^(1) r/m byte by 2,
					  imm8 times

C1   /4 ib      SAL r/m16,imm8    3/7     Multiply r/m word by 2, imm8
					  times
C1   /5 ib      SHR r/m32,imm8    3/7     Unsigned divide r/m dword by 2,
					  imm8 times
C1   /7 ib      SAR r/m16,imm8    3/7     Signed divide^(1) r/m word by 2,
					  imm8 times

D0   /4         SAL r/m8,1        3/7     Multiply r/m byte by 2, once
D0   /5         SHR r/m8,1        3/7     Unsigned divide r/m byte by 2,
					  once
D0   /7         SAR r/m8,1        3/7     Signed divide^(1) r/m byte by 2,
					  once

D1   /4         SAL r/m16,1       3/7     Multiply r/m word by 2, once
D1   /5         SHR r/m16,1       3/7     Unsigned divide r/m word by 2,
					  once
D1   /7         SAR r/m16,1       3/7     Signed divide^(1) r/m word by 2,
					  once

D2   /4         SAL r/m8,CL       3/7     Multiply r/m byte by 2, CL times
D2   /5         SHR r/m8,CL       3/7     Unsigned divide r/m byte by 2,
					  CL times
D2   /7         SAR r/m8,CL       3/7     Signed divide^(1) r/m byte by 2,
					  CL times

D3   /4         SAL r/m16,CL      3/7     Multiply r/m word by 2, CL times
D3   /5         SHR r/m32,CL      3/7     Unsigned divide r/m dword by 2,
					  CL times
D3   /7         SAR r/m16,CL      3/7     Signed divide^(1) r/m word by 2,
					  CL 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

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
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
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
83  /3 ib    SBB r/m16,imm8    2/7     Subtract with borrow sign-extended
				       immediate byte from r/m word


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

see REP also

Operation

IF AddressSize = 16
THEN use DI for dest-index;
ELSE (* AddressSize = 32 *) use  DI 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 *)
       A  - [dest-index];(* compare dword in  A  & 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  A  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  DI 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  DI 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  C  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

			      Set byte if...
0F  90   SETO r/m8    4/5     (OF=1)
0F  91   SETNO r/m8   4/5     (OF=0)
0F  92   SETB r/m8    4/5     (CF=1)
0F  93   SETAE r/m8   4/5     (CF=0)
0F  94   SETE r/m8    4/5     (ZF=1)
0F  95   SETNE r/m8   4/5     (ZF=0)
0F  96   SETBE r/m8   4/5     (ZF=1)
0F  97   SETA r/m8    4/5     (CF=0 and ZF=0)
0F  98   SETS r/m8    4/5     (SF=1)
0F  99   SETNS r/m8   4/5     (SF=0)
0F  9A   SETP r/m8    4/5     (PF=1)
0F  9B   SETNP r/m8   4/5     (PF=0)
0F  9C   SETL r/m8    4/5     (SF<>OF)
0F  9D   SETGE r/m8   4/5     (SF=OF)
0F  9E   SETLE r/m8   4/5     (ZF=1 and SF<>OF)
0F  9F   SETG r/m8    4/5     (ZF=0 or SF=OF)



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  A5   SHLD r/m16,r16,CL    3/7      r/m16 gets SHL of r/m16 concatenated
				       with r16


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  AD   SHRD r/m16,r16,CL     3/7     r/m16 gets SHR of r/m16 concatenated
				       with r16


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

FB     STI           3        Set interrupt flag; interrupts enabled at the
			       end of the next instruction

eh? INTeL typo, opcode F13. Hmmmm. The opcode map says FB.

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 restriction level is greater than the I/O
restriction level

Real Address Mode Exceptions

None

Virtual 8086 Mode Exceptions

None


STOS/STOSB/STOSW/STOSD .. Store String Data

Opcode  Instruction  Clocks   Description

AA      STOSB 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

I don't see what the point of ther memory operands are. It seems to be an
artifact of the INTeL assembler discussed below.

Operation

IF AddressSize = 16
THEN use ES:DI for DestReg
ELSE (* AddressSize = 32 *) use ES: DI 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) <!  A ;
      IF DF = 0
      THEN DestReg <! DestReg + 4;
      ELSE DestReg <! DestReg - 4;
      FI;
   FI;
FI;

Description

STOS transfers the contents of all AL, AX, or  A  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
 DI 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  C  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

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
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
2C  ib      SUB AL,imm8      2        Subtract immediate byte from AL
2D  iw      SUB AX,imm16     2        Subtract immediate word from AX
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
83  /5 ib   SUB r/m16,imm8   2/7      Subtract sign-extended immediate byte
				      from r/m word

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

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
A8   ib      TEST AL,imm8      2        AND immediate byte with AL
A9   iw      TEST AX,imm16     2        AND immediate word with AX
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


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 restriction
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
     restriction level (DRL) can be any value for VERR. Otherwise, the
     DRL must be greater than or equal to both the current restriction 
     level and the selector's RRL.

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
86  /r    XCHG r/m8,r8     3          Exchange byte register with EA byte
87  /r    XCHG r/m16,r16   3          Exchange word register with EA word

I don't know what EA signifies. 

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 IORL.

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 <! ( B  + 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: B  (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/ B  with a previous
instruction.

Once again this spurious operand seems like an artifact of some ancient
INTeL assembler. Segment prefixes don't know if the following instruction
has an argument.

The no-operand form, XLATB, can be used if the BX/B  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

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
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
34  ib      XOR AL,imm8      2        Exclusive-OR immediate byte to AL
35  iw      XOR AX,imm16     2        Exclusive-OR immediate word to AX
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
83  /6 ib   XOR r/m16,imm8   2/7      XOR sign-extended immediate byte
				      with r/m word


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


Appendix A  Opcode Map
