Search or: and:
 LINUX
 Language
 Kernel
 Package
 Book
 Test
 OS
 Forum
Оригинал лежит тут

OpcodeInstructionClocks DescriptionExample

## Operation

```

IF ((AL AND 0FH) > 9) OR (AF = 1)
THEN
AL := (AL + 6) AND 0FH;
AH := AH + 1;
AF := 1;
CF := 1;
ELSE
CF := 0;
AF := 0;
FI;
```

## Description

Execute AAA only following an ADD instruction that leaves a byte result in the AL register. The lower nibbles of the operands of the ADD instruction should be in the range 0 through 9 (BCD digits). In this case, AAA adjusts AL to contain the correct decimal digit result. If the addition produced a decimal carry, the AH register is incremented, and the carry and auxiliary carry flags are set to 1. If there was no decimal carry, the carry and auxiliary flags are set to 0 and AH is unchanged. In either case, AL is left with its top nibble set to 0. To convert AL to an ASCII result, follow the AAA instruction with OR AL, 30H.

## Flags Affected

AF and CF as described above; OF, SF, ZF, and PF are undefined

## Protected Mode Exceptions

None

None

OpcodeInstructionClocks DescriptionExample

## Operation

```

AL := AH * 10 + AL;
AH := 0;
```

## Description

AAD is used to prepare two unpacked BCD digits (the least-significant digit in AL, the most-significant digit in AH) for a division operation that will yield an unpacked result. This is accomplished by setting AL to AL + (10 * AH), and then setting AH to 0. AX is then equal to the binary equivalent of the original unpacked two-digit number.

## Flags Affected

SF, ZF, and PF as described in Appendix C; OF, AF, and CF are undefined

None

None

None

# AAM -- ASCII Adjust AX after Multiply

OpcodeInstructionClocks DescriptionExample
D4 0Aaam 17 ASCII adjust AX after multiplyaam

## Operation

```

AH := AL / 10;
AL := AL MOD 10;
```

## Description

Execute AAM only after executing a MUL instruction between two unpacked BCD digits that leaves the result in the AX register. Because the result is less than 100, it is contained entirely in the AL register. AAM unpacks the AL result by dividing AL by 10, leaving the quotient (most-significant digit) in AH and the remainder (least-significant digit) in AL.

## Flags Affected

SF, ZF, and PF as described in Appendix C; OF, AF, and CF are undefined

None

None

None

# AAS -- ASCII Adjust AL after Subtraction

OpcodeInstructionClocks DescriptionExample
3Faas 4 ASCII adjust AL after subtractionaas

## Operation

```

IF (AL AND 0FH) > 9 OR AF = 1
THEN
AL := AL - 6;
AL := AL AND 0FH;
AH := AH - 1;
AF := 1;
CF := 1;
ELSE
CF := 0;
AF := 0;
FI;
```

## Description

Execute AAS only after a SUB instruction that leaves the byte result in the AL register. The lower nibbles of the operands of the SUB instruction must have been in the range 0 through 9 (BCD digits). In this case, AAS adjusts AL so it contains the correct decimal digit result. If the subtraction produced a decimal carry, the AH register is decremented, and the carry and auxiliary carry flags are set to 1. If no decimal carry occurred, the carry and auxiliary carry flags are set to 0, and AH is unchanged. In either case, AL is left with its top nibble set to 0. To convert AL to an ASCII result, follow the AAS with OR AL, 30H.

## Flags Affected

AF and CF as described above; OF, SF, ZF, and PF are undefined

None

None

## Virtual 8086 Mode Exceptions

None

OpcodeInstructionClocks DescriptionExample

## 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

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

OpcodeInstructionClocks DescriptionExample

## 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

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

OpcodeInstructionClocks DescriptionExample
24 ibandb imm8,al2 AND immediate byte to ALandb \$0x7f,%al
25 iwandw imm16,ax2 AND immediate word to AXandw \$0x7fff,%ax
25 idandl imm32,eax2 AND immediate dword to EAXandl \$0x7fffffff,%eax
80 /4 ibandb imm8,r/m82/7 AND immediate byte to r/m byteandb \$0x7f,%dl
andb \$0x7f,(%ebx,1)
andb \$0x7f,m8(%ebx,1)
andb \$0x7f,m8(%ebx,%ebp,1)
81 /4 iwandw imm16,r/m162/7 AND immediate word to r/m wordandw \$0x7fff,%cx
andw \$0x7fff,(%ebx,1)
andw \$0x7fff,(%ebx,2)
andw \$0x7fff,(%ebx,%ebp,1)
81 /4 idandl imm32,r/m322/7 AND immediate dword to r/m dwordandl \$0x7fffffff,%ecx
andl \$0x7fffffff,(%ebx,2)
andl \$0x7fffffff,(%ebx,4)
andl \$0x7fffffff,(%ebx,%ebp,1)
83 /4 ibandw imm8,r/m162/7 AND sign-extended immediate byte with r/m wordandw \$0x7f,%cx
andw \$0x7f,(%ebx,1)
andw \$0x7f,(%ebx,2)
andw \$0x7f,(%ebx,%ebp,1)
83 /4 ibandl imm8,r/m322/7 AND sign-extended immediate byte with r/m dwordandl \$0x7f,%ecx
andl \$0x7f,(%ebx,2)
andl \$0x7f,(%ebx,4)
andl \$0x7f,(%ebx,%ebp,1)
20 /randb r8,r/m82/7 AND byte register to r/m byteandb %bh,%dl
andb %bh,(%ebx,1)
andb %bh,m8(%ebx,1)
andb %bh,m8(%ebx,%ebp,1)
21 /randw r16,r/m162/7 AND word register to r/m wordandw %bx,%cx
andw %bx,(%ebx,1)
andw %bx,(%ebx,2)
andw %bx,(%ebx,%ebp,1)
21 /randl r32,r/m322/7 AND dword register to r/m dwordandl %ebx,%ecx
andl %ebx,(%ebx,2)
andl %ebx,(%ebx,4)
andl %ebx,(%ebx,%ebp,1)
22 /randb r/m8,r82/6 AND r/m byte to byte registerandb %dl,%bh
andb (%ebx,1),%bh
andb m8(%ebx,1),%bh
andb m8(%ebx,%ebp,1),%bh
23 /randw r/m16,r162/6 AND r/m word to word registerandw %cx,%bx
andw (%ebx,1),%bx
andw (%ebx,2),%bx
andw (%ebx,%ebp,1),%bx
23 /randl r/m32,r322/6 AND r/m dword to dword registerandl %ecx,%ebx
andl (%ebx,2),%ebx
andl (%ebx,4),%ebx
andl (%ebx,%ebp,1),%ebx

## 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

Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH

## Virtual 8086 Mode Exceptions

Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault

# ARPL -- Adjust RPL Field of Selector

OpcodeInstructionClocks DescriptionExample
63 /rarplw r16,r/m16pm=20/21 Adjust RPL of r/m16 to not less than RPL of r16arplw %bx,%cx
arplw %bx,(%ebx,1)
arplw %bx,(%ebx,2)
arplw %bx,(%ebx,%ebp,1)

## Operation

```

IF RPL bits(0,1) of DEST < RPL bits(0,1) of SRC
THEN
ZF := 1;
RPL bits(0,1) of DEST := RPL bits(0,1) of SRC;
ELSE
ZF := 0;
FI;
```

## Description

The ARPL instruction has two operands. The first operand is a 16-bit memory variable or word register that contains the value of a selector. The second operand is a word register. If the RPL field ("requested privilege level"--bottom two bits) of the first operand is less than the RPL field of the second operand, the zero flag is set to 1 and the RPL field of the first operand is increased to match the second operand. Otherwise, the zero flag is set to 0 and no change is made to the first operand.

ARPL appears in operating system software, not in application programs. It is used to guarantee that a selector parameter to a subroutine does not request more privilege than the caller is allowed. The second operand of ARPL is normally a register that contains the CS selector value of the caller.

## Flags Affected

ZF as described above

## Protected Mode Exceptions

#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal memory operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page fault

Interrupt 6; ARPL is not recognized in Real Address Mode

## Virtual 8086 Mode Exceptions

Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault

# BOUND -- Check Array Index Against Bounds

OpcodeInstructionClocks DescriptionExample
62 /rboundw r16,m16&1610 Check if r16 is within bounds (passes test)boundw %bx,m16
62 /rboundl r32,m32&3210 Check if r32 is within bounds (passes test)boundl %ebx,m32

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

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.

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

OpcodeInstructionClocks DescriptionExample
0F BCbsfw r/m16,r1610+3n Bit scan forward on r/m wordbsfw %cx,%bx
bsfw (%ebx,1),%bx
bsfw (%ebx,2),%bx
bsfw (%ebx,%ebp,1),%bx
0F BCbsfl r/m32,r3210+3n Bit scan forward on r/m dwordbsfl %ecx,%ebx
bsfl (%ebx,2),%ebx
bsfl (%ebx,4),%ebx
bsfl (%ebx,%ebp,1),%ebx

## 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

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

OpcodeInstructionClocks DescriptionExample
0F BDbsrw r/m16,r1610+3n Bit scan reverse on r/m wordbsrw %cx,%bx
bsrw (%ebx,1),%bx
bsrw (%ebx,2),%bx
bsrw (%ebx,%ebp,1),%bx
0F BDbsrl r/m32,r3210+3n Bit scan reverse on r/m dwordbsrl %ecx,%ebx
bsrl (%ebx,2),%ebx
bsrl (%ebx,4),%ebx
bsrl (%ebx,%ebp,1),%ebx

## 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

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

OpcodeInstructionClocks DescriptionExample
0F A3btw r16,r/m163/12 Save bit in carry flagbtw %bx,%cx
btw %bx,(%ebx,1)
btw %bx,(%ebx,2)
btw %bx,(%ebx,%ebp,1)
0F A3btl r32,r/m323/12 Save bit in carry flagbtl %ebx,%ecx
btl %ebx,(%ebx,2)
btl %ebx,(%ebx,4)
btl %ebx,(%ebx,%ebp,1)
0F BA /4 ibbtw imm8,r/m163/6 Save bit in carry flagbtw \$0x7f,%cx
btw \$0x7f,(%ebx,1)
btw \$0x7f,(%ebx,2)
btw \$0x7f,(%ebx,%ebp,1)
0F BA /4 ibbtl imm8,r/m323/6 Save bit in carry flagbtl \$0x7f,%ecx
btl \$0x7f,(%ebx,2)
btl \$0x7f,(%ebx,4)
btl \$0x7f,(%ebx,%ebp,1)

## 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

Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH

## Virtual 8086 Mode Exceptions

Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault

## Notes

The index of the selected bit can be given by the immediate constant in the instruction or by a value in a general register. Only an 8-bit immediate value is used in the instruction. This operand is taken modulo 32, so the range of immediate bit offsets is 0..31. This allows any bit within a register to be selected. For memory bit strings, this immediate field gives only the bit offset within a word or doubleword. Immediate bit offsets larger than 31 are supported by using the immediate bit offset field in combination with the displacement field of the memory operand. The low-order 3 to 5 bits of the immediate bit offset are stored in the immediate bit offset field, and the high-order 27 to 29 bits are shifted and combined with the byte displacement in the addressing mode.

When accessing a bit in memory, the 80386 may access four bytes starting from the memory address given by:

```

Effective Address + (4 * (BitOffset DIV 32))
```
for a 32-bit operand size, or two bytes starting from the memory address given by:
```

Effective Address + (2 * (BitOffset DIV 16))
```
for a 16-bit operand size. It may do so even when only a single byte needs to be accessed in order to reach the given bit. You must therefore avoid referencing areas of memory close to address space holes. In particular, avoid references to memory-mapped I/O registers. Instead, use the MOV instructions to load from or store to these addresses, and use the register form of these instructions to manipulate the data.

# BTC -- Bit Test and Complement

OpcodeInstructionClocks DescriptionExample
0F BBbtcw r16,r/m166/13 Save bit in carry flag and complementbtcw %bx,%cx
btcw %bx,(%ebx,1)
btcw %bx,(%ebx,2)
btcw %bx,(%ebx,%ebp,1)
0F BBbtcl r32,r/m326/13 Save bit in carry flag and complementbtcl %ebx,%ecx
btcl %ebx,(%ebx,2)
btcl %ebx,(%ebx,4)
btcl %ebx,(%ebx,%ebp,1)
0F BA /7 ibbtcw imm8,r/m166/8 Save bit in carry flag and complementbtcw \$0x7f,%cx
btcw \$0x7f,(%ebx,1)
btcw \$0x7f,(%ebx,2)
btcw \$0x7f,(%ebx,%ebp,1)
0F BA /7 ibbtcl imm8,r/m326/8 Save bit in carry flag and complementbtcl \$0x7f,%ecx
btcl \$0x7f,(%ebx,2)
btcl \$0x7f,(%ebx,4)
btcl \$0x7f,(%ebx,%ebp,1)

## 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

Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH

## Virtual 8086 Mode Exceptions

Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault

## Notes

The index of the selected bit can be given by the immediate constant in the instruction or by a value in a general register. Only an 8-bit immediate value is used in the instruction. This operand is taken modulo 32, so the range of immediate bit offsets is 0..31. This allows any bit within a register to be selected. For memory bit strings, this immediate field gives only the bit offset within a word or doubleword. Immediate bit offsets larger than 31 are supported by using the immediate bit offset field in combination with the displacement field of the memory operand. The low-order 3 to 5 bits of the immediate bit offset are stored in the immediate bit offset field, and the high-order 27 to 29 bits are shifted and combined with the byte displacement in the addressing mode.

When accessing a bit in memory, the 80386 may access four bytes starting from the memory address given by:

```

Effective Address + (4 * (BitOffset DIV 32))
```
for a 32-bit operand size, or two bytes starting from the memory address given by:
```

Effective Address + (2 * (BitOffset DIV 16))
```
for a 16-bit operand size. It may do so even when only a single byte needs to be accessed in order to reach the given bit. You must therefore avoid referencing areas of memory close to address space holes. In particular, avoid references to memory-mapped I/O registers. Instead, use the MOV instructions to load from or store to these addresses, and use the register form of these instructions to manipulate the data.

# BTR -- Bit Test and Reset

OpcodeInstructionClocks DescriptionExample
0F B3btrw r16,r/m166/13 Save bit in carry flag and resetbtrw %bx,%cx
btrw %bx,(%ebx,1)
btrw %bx,(%ebx,2)
btrw %bx,(%ebx,%ebp,1)
0F B3btrl r32,r/m326/13 Save bit in carry flag and resetbtrl %ebx,%ecx
btrl %ebx,(%ebx,2)
btrl %ebx,(%ebx,4)
btrl %ebx,(%ebx,%ebp,1)
0F BA /6 ibbtrw imm8,r/m166/8 Save bit in carry flag and resetbtrw \$0x7f,%cx
btrw \$0x7f,(%ebx,1)
btrw \$0x7f,(%ebx,2)
btrw \$0x7f,(%ebx,%ebp,1)
0F BA /6 ibbtrl imm8,r/m326/8 Save bit in carry flag and resetbtrl \$0x7f,%ecx
btrl \$0x7f,(%ebx,2)
btrl \$0x7f,(%ebx,4)
btrl \$0x7f,(%ebx,%ebp,1)

## 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

Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH

## Virtual 8086 Mode Exceptions

Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault

## Notes

The index of the selected bit can be given by the immediate constant in the instruction or by a value in a general register. Only an 8-bit immediate value is used in the instruction. This operand is taken modulo 32, so the range of immediate bit offsets is 0..31. This allows any bit within a register to be selected. For memory bit strings, this immediate field gives only the bit offset within a word or doubleword. Immediate bit offsets larger than 31 (or 15) are supported by using the immediate bit offset field in combination with the displacement field of the memory operand. The low-order 3 to 5 bits of the immediate bit offset are stored in the immediate bit offset field, and the high-order 27 to 29 bits are shifted and combined with the byte displacement in the addressing mode.

When accessing a bit in memory, the 80386 may access four bytes starting from the memory address given by:

```

Effective Address + 4 * (BitOffset DIV 32)
```
for a 32-bit operand size, or two bytes starting from the memory address given by:
```

Effective Address + 2 * (BitOffset DIV 16)
```
for a 16-bit operand size. It may do so even when only a single byte needs to be accessed in order to reach the given bit. You must therefore avoid referencing areas of memory close to address space holes. In particular, avoid references to memory-mapped I/O registers. Instead, use the MOV instructions to load from or store to these addresses, and use the register form of these instructions to manipulate the data.

# BTS -- Bit Test and Set

OpcodeInstructionClocks DescriptionExample
0F ABbtsw r16,r/m166/13 Save bit in carry flag and setbtsw %bx,%cx
btsw %bx,(%ebx,1)
btsw %bx,(%ebx,2)
btsw %bx,(%ebx,%ebp,1)
0F ABbtsl r32,r/m326/13 Save bit in carry flag and setbtsl %ebx,%ecx
btsl %ebx,(%ebx,2)
btsl %ebx,(%ebx,4)
btsl %ebx,(%ebx,%ebp,1)
0F BA /5 ibbtsw imm8,r/m166/8 Save bit in carry flag and setbtsw \$0x7f,%cx
btsw \$0x7f,(%ebx,1)
btsw \$0x7f,(%ebx,2)
btsw \$0x7f,(%ebx,%ebp,1)
0F BA /5 ibbtsl imm8,r/m326/8 Save bit in carry flag and setbtsl \$0x7f,%ecx
btsl \$0x7f,(%ebx,2)
btsl \$0x7f,(%ebx,4)
btsl \$0x7f,(%ebx,%ebp,1)

## 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

Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH

## Virtual 8086 Mode Exceptions

Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault

## Notes

The index of the selected bit can be given by the immediate constant in the instruction or by a value in a general register. Only an 8-bit immediate value is used in the instruction. This operand is taken modulo 32, so the range of immediate bit offsets is 0..31. This allows any bit within a register to be selected. For memory bit strings, this immediate field gives only the bit offset within a word or doubleword. Immediate bit offsets larger than 31 are supported by using the immediate bit offset field in combination with the displacement field of the memory operand. The low-order 3 to 5 bits of the immediate bit offset are stored in the immediate bit offset field, and the high order 27 to 29 bits are shifted and combined with the byte displacement in the addressing mode.

When accessing a bit in memory, the processor may access four bytes starting from the memory address given by:

```

Effective Address + (4 * (BitOffset DIV 32))
```
for a 32-bit operand size, or two bytes starting from the memory address given by:
```

Effective Address + (2 * (BitOffset DIV 16))
```
for a 16-bit operand size. It may do this even when only a single byte needs to be accessed in order to get at the given bit. Thus the programmer must be careful to avoid referencing areas of memory close to address space holes. In particular, avoid references to memory-mapped I/O registers. Instead, use the MOV instructions to load from or store to these addresses, and use the register form of these instructions to manipulate the data.

# CALL -- Call Procedure

OpcodeInstructionClocks DescriptionExample
E8 cwcall rel167+m Call near, displacement relative to next instructioncall rel16
FF /2callw r/m167+m/10+m Call near, register indirect/memory indirectcallw *%cx
callw *(%ebx,1)
callw (%ebx,2)
callw (%ebx,%ebp,1)
9A cdcallw ptr16:1617+m,pm=34+m Call intersegment, to full pointer givencallw *(%ebx,1)
9A cdcallw ptr16:16pm=52+m Call gate, same privilegecallw *(%ebx,1)
9A cdcallw ptr16:16pm=86+m Call gate, more privilege, no parameterscallw *(%ebx,1)
9A cdcallw ptr16:16pm=94+4x+m Call gate, more privilege, x parameterscallw *(%ebx,1)
9A cdcallw ptr16:16ts Call to taskcallw *(%ebx,1)
FF /3callw m16:1622+m,pm=38+m Call intersegment, address at r/m dwordcall tocall
FF /3callw m16:16pm=56+m Call gate, same privilegecall tocall
FF /3callw m16:16pm=90+m Call gate, more privilege, no parameterscall tocall
FF /3callw m16:16pm=98+4x+m Call gate, more privilege, x parameterscall tocall
FF /3callw m16:165 + ts Call to taskcall tocall
E8 cdcall rel327+m Call near, displacement relative to next instructioncall rel32
FF /2calll r/m327+m/10+m Call near, indirectcalll *%ecx
calll *(%ebx,2)
calll (%ebx,4)
calll (%ebx,%ebp,1)
9A cpcallw ptr16:3217+m,pm=34+m Call intersegment, to full pointer givencallw *(%ebx,1)
9A cpcallw ptr16:32pm=52+m Call gate, same privilegecallw *(%ebx,1)
9A cpcallw ptr16:32pm=86+m Call gate, more privilege, no parameterscallw *(%ebx,1)
9A cpcalll ptr32:32pm=94+4x+m Call gate, more privilege, x parameterscalll *(%ebx,1)
9A cpcallw ptr16:32ts Call to taskcallw *(%ebx,1)
FF /3callw m16:3222+m,pm=38+m Call intersegment, address at r/m dwordcall tocall
FF /3callw m16:32pm=56+m Call gate, same privilegecall tocall
FF /3callw m16:32pm=90+m Call gate, more privilege, no parameterscall tocall
FF /3callw m16:32pm=98+4x+m Call gate, more privilege, x parameterscall tocall
FF /3callw m16:325 + ts Call to taskcall tocall

### Note

Values of ts are given by the following table:
```

386 TSS         386 TSS         286 TSS
Old         VM = 0          VM = 1

N     Y         N     Y         N     Y

386          300   309       217   226       273   282
TSS VM=0

286          298   307       217   226       273   282
TSS
```

## Operation

```

IF rel16 or rel32 type of call
THEN (* near relative call *)
IF OperandSize = 16
THEN
Push(IP);
EIP := (EIP + rel16) AND 0000FFFFH;
ELSE (* OperandSize = 32 *)
Push(EIP);
EIP := EIP + rel32;
FI;
FI;

IF r/m16 or r/m32 type of call
THEN (* near absolute call *)
IF OperandSize = 16
THEN
Push(IP);
EIP := [r/m16] AND 0000FFFFH;
ELSE (* OperandSize = 32 *)
Push(EIP);
EIP := [r/m32];
FI;
FI;

IF (PE = 0 OR (PE = 1 AND VM = 1))
(* real mode or virtual 8086 mode *)
AND instruction = far CALL
(* i.e., operand type is m16:16, m16:32, ptr16:16, ptr16:32 *)
THEN
IF OperandSize = 16
THEN
Push(CS);
Push(IP); (* address of next instruction; 16 bits *)
ELSE
Push(CS); (* padded with 16 high-order bits *)
Push(EIP); (* address of next instruction; 32 bits *)
FI;
IF operand type is m16:16 or m16:32
THEN (* indirect far call *)
IF OperandSize = 16
THEN
CS:IP := [m16:16];
EIP := EIP AND 0000FFFFH; (* clear upper 16 bits *)
ELSE (* OperandSize = 32 *)
CS:EIP := [m16:32];
FI;
FI;
IF operand type is ptr16:16 or ptr16:32
THEN (* direct far call *)
IF OperandSize = 16
THEN
CS:IP := ptr16:16;
EIP := EIP AND 0000FFFFH; (* clear upper 16 bits *)
ELSE (* OperandSize = 32 *)
CS:EIP := ptr16:32;
FI;
FI;
FI;

IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)
AND instruction = far CALL
THEN
If indirect, then check access of EA doubleword;
#GP(0) if limit violation;
New CS selector must not be null else #GP(0);
Check that new CS selector index is within its
descriptor table limits; else #GP(new CS selector);
Examine AR byte of selected descriptor for various legal values;
depending on value:
go to CONFORMING-CODE-SEGMENT;
go to NONCONFORMING-CODE-SEGMENT;
go to CALL-GATE;
ELSE #GP(code segment selector);
FI;

CONFORMING-CODE-SEGMENT:
DPL must be <= CPL ELSE #GP(code segment selector);
Segment must be present ELSE #NP(code segment selector);
Stack must be big enough for return address ELSE #SS(0);
Instruction pointer must be in code segment limit ELSE #GP(0);
Load code segment descriptor into CS register;
Load CS with new code segment selector;
IF OperandSize=16 THEN EIP := EIP AND 0000FFFFH; FI;

NONCONFORMING-CODE-SEGMENT:
RPL must be <= CPL ELSE #GP(code segment selector)
DPL must be = CPL ELSE #GP(code segment selector)
Segment must be present ELSE #NP(code segment selector)
Stack must be big enough for return address ELSE #SS(0)
Instruction pointer must be in code segment limit ELSE #GP(0)
Load code segment descriptor into CS register
Load CS with new code segment selector
Set RPL of CS to CPL
IF OperandSize=16 THEN EIP := EIP AND 0000FFFFH; FI;

CALL-GATE:
Call gate DPL must be >= CPL ELSE #GP(call gate selector)
Call gate DPL must be >= RPL ELSE #GP(call gate selector)
Call gate must be present ELSE #NP(call gate selector)
Examine code segment selector in call gate descriptor:
Selector must not be null ELSE #GP(0)
Selector must be within its descriptor table
limits ELSE #GP(code segment selector)
AR byte of selected descriptor must indicate code
segment ELSE #GP(code segment selector)
DPL of selected descriptor must be <= CPL ELSE
#GP(code segment selector)
IF non-conforming code segment AND DPL < CPL
THEN go to MORE-PRIVILEGE
ELSE go to SAME-PRIVILEGE
FI;

MORE-PRIVILEGE:
Get new SS selector for new privilege level from TSS
Check selector and descriptor for new SS:
Selector must not be null ELSE #TS(0)
Selector index must be within its descriptor
table limits ELSE #TS(SS selector)
Selector's RPL must equal DPL of code segment
ELSE #TS(SS selector)
Stack segment DPL must equal DPL of code
segment ELSE #TS(SS selector)
Descriptor must indicate writable data segment
ELSE #TS(SS selector)
Segment present ELSE #SS(SS selector)
IF OperandSize=32
THEN
New stack must have room for parameters plus 16 bytes
ELSE #SS(0)
EIP must be in code segment limit ELSE #GP(0)
Load new SS:eSP value from TSS
Load new CS:EIP value from gate
ELSE
New stack must have room for parameters plus 8 bytes ELSE #SS(0)
IP must be in code segment limit ELSE #GP(0)
Load new SS:eSP value from TSS
Load new CS:IP value from gate
FI;
Push long pointer of old stack onto new stack
Get word count from call gate, mask to 5 bits
Copy parameters from old stack onto new stack
Push return address onto new stack
Set CPL to stack segment DPL
Set RPL of CS to CPL

SAME-PRIVILEGE:
IF OperandSize=32
THEN
Stack must have room for 6-byte return address (padded to 8 bytes)
ELSE #SS(0)
EIP must be within code segment limit ELSE #GP(0)
ELSE
Stack must have room for 4-byte return address ELSE #SS(0)
IP must be within code segment limit ELSE #GP(0)
FI;
Load code segment descriptor into CS register
Set RPL of CS to CPL

Task gate DPL must be >= CPL ELSE #TS(gate selector)
Task gate DPL must be >= RPL ELSE #TS(gate selector)
Task Gate must be present ELSE #NP(gate selector)
Examine selector to TSS, given in Task Gate descriptor:
Must specify global in the local/global bit ELSE #TS(TSS selector)
Index must be within GDT limits ELSE #TS(TSS selector)
TSS descriptor AR byte must specify nonbusy TSS
ELSE #TS(TSS selector)
Task State Segment must be present ELSE #NP(TSS selector)
IP must be in code segment limit ELSE #TS(0)

TSS DPL must be >= CPL else #TS(TSS selector)
TSS DPL must be >= RPL ELSE #TS(TSS selector)
TSS descriptor AR byte must specify available TSS
ELSE #TS(TSS selector)
Task State Segment must be present ELSE #NP(TSS selector)
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
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

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

OpcodeInstructionClocks DescriptionExample
98cbw 3 AX := sign-extend of ALcbw
98cwde 3 EAX := sign-extend of AXcwde

## Operation

```

IF OperandSize = 16 (* instruction = CBW *)
THEN AX := SignExtend(AL);
ELSE (* OperandSize = 32, instruction = CWDE *)
EAX := SignExtend(AX);
FI;
```

## Description

CBW converts the signed byte in AL to a signed word in AX by extending the most significant bit of AL (the sign bit) into all of the bits of AH. CWDE converts the signed word in AX to a doubleword in EAX by extending the most significant bit of AX into the two most significant bytes of EAX. Note that CWDE is different from CWD. CWD uses DX:AX rather than EAX as a destination.

None

None

None

None

# CLC -- Clear Carry Flag

OpcodeInstructionClocks DescriptionExample
F8clc 2 Clear carry flagclc

```

CF := 0;
```

## Description

CLC sets the carry flag to zero. It does not affect other flags or registers.

CF := 0

None

None

None

# CLD -- Clear Direction Flag

OpcodeInstructionClocks DescriptionExample
FCcld 2 Clear direction flagcld

```

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.

DF := 0

None

None

None

# CLI -- Clear Interrupt Flag

OpcodeInstructionClocks DescriptionExample
FAcli 3 Clear interrupt flagcli

```

IF := 0;
```

## Description

CLI clears the interrupt flag if the current privilege level is at least as privileged as IOPL. No other flags are affected. External interrupts are not recognized at the end of the CLI instruction or from that point on until the interrupt flag is set.

IF := 0

## Protected Mode Exceptions

#GP(0) if the current privilege level is greater (has less privilege) than the IOPL in the flags register. IOPL specifies the least privileged level at which I/O can be performed.

None

## Virtual 8086 Mode Exceptions

#GP(0) as for Protected Mode

# CLTS -- Clear Task-Switched Flag in CR0

OpcodeInstructionClocks DescriptionExample
OF 06clts 5 Clear task-switched flagclts

## Operation

```

TS Flag in CR0 := 0;
```

## Description

CLTS clears the task-switched (TS) flag in register CR0. This flag is set by the 80386 every time a task switch occurs. The TS flag is used to manage processor extensions as follows:
• Every execution of an ESC instruction is trapped if the TS flag is set.
• Execution of a WAIT instruction is trapped if the MP flag and the TS flag are both set.
Thus, if a task switch was made after an ESC instruction was begun, the processor extension's context may need to be saved before a new ESC instruction can be issued. The fault handler saves the context and resets the TS flag.

CLTS appears in operating system software, not in application programs. It is a privileged instruction that can only be executed at privilege level 0.

## Flags Affected

TS := 0 (TS is in CR0, not the flag register)

## Protected Mode Exceptions

#GP(0) if CLTS is executed with a current privilege level other than 0

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

OpcodeInstructionClocks DescriptionExample
F5cmc 2 Complement carry flagcmc

```

CF := NOT CF;
```

## Description

CMC reverses the setting of the carry flag. No other flags are affected.

## Flags Affected

CF as described above

None

None

None

# CMP -- Compare Two Operands

OpcodeInstructionClocks DescriptionExample
3C ibcmpb imm8,al2 Compare immediate byte to ALcmpb \$0x7f,%al
3D iwcmpw imm16,ax2 Compare immediate word to AXcmpw \$0x7fff,%ax
3D idcmpl imm32,eax2 Compare immediate dword to EAXcmpl \$0x7fffffff,%eax
80 /7 ibcmpb imm8,r/m82/5 Compare immediate byte to r/m bytecmpb \$0x7f,%dl
cmpb \$0x7f,(%ebx,1)
cmpb \$0x7f,m8(%ebx,1)
cmpb \$0x7f,m8(%ebx,%ebp,1)
81 /7 iwcmpw imm16,r/m162/5 Compare immediate word to r/m wordcmpw \$0x7fff,%cx
cmpw \$0x7fff,(%ebx,1)
cmpw \$0x7fff,(%ebx,2)
cmpw \$0x7fff,(%ebx,%ebp,1)
81 /7 idcmpl imm32,r/m322/5 Compare immediate dword to r/m dwordcmpl \$0x7fffffff,%ecx
cmpl \$0x7fffffff,(%ebx,2)
cmpl \$0x7fffffff,(%ebx,4)
cmpl \$0x7fffffff,(%ebx,%ebp,1)
83 /7 ibcmpw imm8,r/m162/5 Compare sign extended immediate byte to r/m wordcmpw \$0x7f,%cx
cmpw \$0x7f,(%ebx,1)
cmpw \$0x7f,(%ebx,2)
cmpw \$0x7f,(%ebx,%ebp,1)
83 /7 ibcmpl imm8,r/m322/5 Compare sign extended immediate byte to r/m dwordcmpl \$0x7f,%ecx
cmpl \$0x7f,(%ebx,2)
cmpl \$0x7f,(%ebx,4)
cmpl \$0x7f,(%ebx,%ebp,1)
38 /rcmpb r8,r/m82/5 Compare byte register to r/m bytecmpb %bh,%dl
cmpb %bh,(%ebx,1)
cmpb %bh,m8(%ebx,1)
cmpb %bh,m8(%ebx,%ebp,1)
39 /rcmpw r16,r/m162/5 Compare word register to r/m wordcmpw %bx,%cx
cmpw %bx,(%ebx,1)
cmpw %bx,(%ebx,2)
cmpw %bx,(%ebx,%ebp,1)
39 /rcmpl r32,r/m322/5 Compare dword register to r/m dwordcmpl %ebx,%ecx
cmpl %ebx,(%ebx,2)
cmpl %ebx,(%ebx,4)
cmpl %ebx,(%ebx,%ebp,1)
3A /rcmpb r/m8,r82/6 Compare r/m byte to byte registercmpb %dl,%bh
cmpb (%ebx,1),%bh
cmpb m8(%ebx,1),%bh
cmpb m8(%ebx,%ebp,1),%bh
3B /rcmpw r/m16,r162/6 Compare r/m word to word registercmpw %cx,%bx
cmpw (%ebx,1),%bx
cmpw (%ebx,2),%bx
cmpw (%ebx,%ebp,1),%bx
3B /rcmpl r/m32,r322/6 Compare r/m dword to dword registercmpl %ecx,%ebx
cmpl (%ebx,2),%ebx
cmpl (%ebx,4),%ebx
cmpl (%ebx,%ebp,1),%ebx

## 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

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

OpcodeInstructionClocks DescriptionExample
A6cmpsb 10 Compare bytes ES:[(E)DI] with DS:[SI]cmpsb
A7cmpsw 10 Compare words ES:[(E)DI] with DS:[SI]cmpsw
A7cmpsl 10 Compare dwords ES:[(E)DI] with DS:[SI]cmpsl

## Operation

```

IF (instruction = CMPSD) OR
(instruction has operands of type DWORD)
THEN OperandSize := 32;
ELSE OperandSize := 16;
FI;
THEN
use SI for source-index and DI for destination-index
ELSE (* AddressSize = 32 *)
use ESI for source-index and EDI for destination-index;
FI;
IF byte type of instruction
THEN
[source-index] - [destination-index]; (* byte comparison *)
IF DF = 0 THEN IncDec := 1 ELSE IncDec := -1; FI;
ELSE
IF OperandSize = 16
THEN
[source-index] - [destination-index]; (* word comparison *)
IF DF = 0 THEN IncDec := 2 ELSE IncDec := -2; FI;
ELSE (* OperandSize = 32 *)
[source-index] - [destination-index]; (* dword comparison *)
IF DF = 0 THEN IncDec := 4 ELSE IncDec := -4; FI;
FI;
FI;
source-index := source-index + IncDec;
destination-index := destination-index + IncDec;
```

## Description

CMPS compares the byte, word, or doubleword pointed to by the source-index register with the byte, word, or doubleword pointed to by the destination-index register.

If the address-size attribute of this instruction is 16 bits, SI and DI will be used for source- and destination-index registers; otherwise ESI and EDI will be used. Load the correct index values into SI and DI (or ESI and EDI) before executing CMPS.

The comparison is done by subtracting the operand indexed by the destination-index register from the operand indexed by the source-index register.

Note that the direction of subtraction for CMPS is [SI] - [DI] or [ESI] - [EDI]. The left operand (SI or ESI) is the source and the right operand (DI or EDI) is the destination. This is the reverse of the usual Intel convention in which the left operand is the destination and the right operand is the source.

The result of the subtraction is not stored; only the flags reflect the change. The types of the operands determine whether bytes, words, or doublewords are compared. For the first operand (SI or ESI), the DS register is used, unless a segment override byte is present. The second operand (DI or EDI) must be addressable from the ES register; no segment override is possible.

After the comparison is made, both the source-index register and destination-index register are automatically advanced. If the direction flag is 0 (CLD was executed), the registers increment; if the direction flag is 1 (STD was executed), the registers decrement. The registers increment or decrement by 1 if a byte is compared, by 2 if a word is compared, or by 4 if a doubleword is compared.

CMPSB, CMPSW and CMPSD are synonyms for the byte, word, and doubleword CMPS instructions, respectively.

CMPS can be preceded by the REPE or REPNE prefix for block comparison of CX or ECX bytes, words, or doublewords. Refer to the description of the REP instruction for more information on this operation.

## Flags Affected

OF, SF, ZF, AF, PF, and CF as described in Appendix C

## Protected Mode Exceptions

#GP(0) for an illegal memory operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page fault

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

OpcodeInstructionClocks DescriptionExample
99cwd 2 DX:AX := sign-extend of AXcwd
99cdq 2 EDX:EAX := sign-extend of EAXcdq

## Operation

```

IF OperandSize = 16 (* CWD instruction *)
THEN
IF AX < 0 THEN DX := 0FFFFH; ELSE DX := 0; FI;
ELSE (* OperandSize = 32, CDQ instruction *)
IF EAX < 0 THEN EDX := 0FFFFFFFFH; ELSE EDX := 0; FI;
FI;
```

## Description

CWD converts the signed word in AX to a signed doubleword in DX:AX by extending the most significant bit of AX into all the bits of DX. CDQ converts the signed doubleword in EAX to a signed 64-bit integer in the register pair EDX:EAX by extending the most significant bit of EAX (the sign bit) into all the bits of EDX. Note that CWD is different from CWDE. CWDE uses EAX as a destination, instead of DX:AX.

## Flags Affected

None

OpcodeInstructionClocks DescriptionExample

## Operation

```

IF ((AL AND 0FH) > 9) OR (AF = 1)
THEN
AL := AL + 6;
AF := 1;
ELSE
AF := 0;
FI;
IF (AL > 9FH) OR (CF = 1)
THEN
AL := AL + 60H;
CF := 1;
ELSE CF := 0;
FI;
```

## Description

Execute DAA only after executing an ADD instruction that leaves a two-BCD-digit byte result in the AL register. The ADD operands should consist of two packed BCD digits. The DAA instruction adjusts AL to contain the correct two-digit packed decimal result.

## Flags Affected

AF and CF as described above; SF, ZF, PF, and CF as described in Appendix C.

# DAS -- Decimal Adjust AL after Subtraction

OpcodeInstructionClocks DescriptionExample
2Fdas 4 Decimal adjust AL after subtractiondas

## Operation

```

IF (AL AND 0FH) > 9 OR AF = 1
THEN
AL := AL - 6;
AF := 1;
ELSE
AF := 0;
FI;
IF (AL > 9FH) OR (CF = 1)
THEN
AL := AL - 60H;
CF := 1;
ELSE CF := 0;
FI;
```

## Description

Execute DAS only after a subtraction instruction that leaves a two-BCD-digit byte result in the AL register. The operands should consist of two packed BCD digits. DAS adjusts AL to contain the correct packed two-digit decimal result.

## Flags Affected

AF and CF as described above; SF, ZF, and PF as described in Appendix C.

# DEC -- Decrement by 1

OpcodeInstructionClocks DescriptionExample
FE /1decb r/m82/6 Decrement r/m byte by 1decb %dl
decb (%ebx,1)
decb m8(%ebx,1)
decb m8(%ebx,%ebp,1)
FF /1decw r/m162/6 Decrement r/m word by 1 Decrement r/m dword by 1decw %cx
decw (%ebx,1)
decw (%ebx,2)
decw (%ebx,%ebp,1)
48+rwdecw r162 Decrement word register by 1decw %bx
48+rwdecl r322 Decrement dword register by 1decl %ebx

## 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

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

OpcodeInstructionClocks DescriptionExample
F6 /6divb r/m8,al14/17 Unsigned divide AX by r/m byte (AL=Quo, AH=Rem)divb %dl,%al
divb (%ebx,1),%al
divb m8(%ebx,1),%al
divb m8(%ebx,%ebp,1),%al
F7 /6divw r/m16,ax22/25 Unsigned divide DX:AX by r/m word (AX=Quo, DX=Rem)divw %cx,%ax
divw (%ebx,1),%ax
divw (%ebx,2),%ax
divw (%ebx,%ebp,1),%ax
F7 /6divl r/m32,eax38/41 Unsigned divide EDX:EAX by r/m dword (EAX=Quo, EDX=Rem)divl %ecx,%eax
divl (%ebx,2),%eax
divl (%ebx,4),%eax
divl (%ebx,%ebp,1),%eax

## Operation

```

temp := dividend / divisor;
IF temp does not fit in quotient
THEN Interrupt 0;
ELSE
quotient := temp;
remainder := dividend MOD (r/m);
FI;
```

### Note

Divisions are unsigned. The divisor is given by the r/m operand. The dividend, quotient, and remainder use implicit registers. Refer to the table under "Description"

## Description

DIV performs an unsigned division. The dividend is implicit; only the divisor is given as an operand. The remainder is always less than the divisor. The type of the divisor determines which registers to use as follows:
```

Size    Dividend     Divisor   Quotient   Remainder
byte    AX           r/m8       AL          AH
word    DX:AX        r/m16      AX          DX
dword   EDX:EAX      r/m32      EAX         EDX
```

## Flags Affected

OF, SF, ZF, AR, PF, CF are undefined.

## Protected Mode Exceptions

Interrupt 0 if the quotient is too large to fit in the designated register (AL, AX, or EAX), or if the divisor is 0; #GP(0) for an illegal memory operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page fault

Interrupt 0 if the quotient is too big to fit in the designated register (AL, AX, or EAX), or if the divisor is 0; Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH

## Virtual 8086 Mode Exceptions

Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault

# ENTER -- Make Stack Frame for Procedure Parameters

OpcodeInstructionClocks DescriptionExample
C8 iw 00enterw imm16,010 Make procedure stack frameenterw \$0x7fff,\$0
C8 iw 01enterw imm16,112 Make stack frame for procedure parametersenterw \$0x7fff,\$1
C8 iw ibenterw imm16,imm815+4(n-1) Make stack frame for procedure parametersenterw \$0x7fff,\$0x7f

## Operation

```

level := level MOD 32
IF OperandSize = 16 THEN Push(BP) ELSE Push (EBP) FI;
(* Save stack pointer *)
frame-ptr := eSP
IF level > 0
THEN (* level is rightmost parameter *)
FOR i := 1 TO level - 1
DO
IF OperandSize = 16
THEN
BP := BP - 2;
Push[BP]
ELSE (* OperandSize = 32 *)
EBP := EBP - 4;
Push[EBP];
FI;
OD;
Push(frame-ptr)
FI;
IF OperandSize = 16 THEN BP := frame-ptr ELSE EBP := frame-ptr; FI;
THEN SP := SP - First operand;
ELSE ESP := ESP - ZeroExtend(First operand);
FI;
```

## Description

ENTER creates the stack frame required by most block-structured high-level languages. The first operand specifies the number of bytes of dynamic storage allocated on the stack for the routine being entered. The second operand gives the lexical nesting level (0 to 31) of the routine within the high-level language source code. It determines the number of stack frame pointers copied into the new stack frame from the preceding frame. BP (or EBP, if the operand-size attribute is 32 bits) is the current stack frame pointer.

If the operand-size attribute is 16 bits, the processor uses BP as the frame pointer and SP as the stack pointer. If the operand-size attribute is 32 bits, the processor uses EBP for the frame pointer and ESP for the stack pointer.

If the second operand is 0, ENTER pushes the frame pointer (BP or EBP) onto the stack; ENTER then subtracts the first operand from the stack pointer and sets the frame pointer to the current stack-pointer value.

For example, a procedure with 12 bytes of local variables would have an ENTER 12,0 instruction at its entry point and a LEAVE instruction before every RET. The 12 local bytes would be addressed as negative offsets from the frame pointer.

None

## Protected Mode Exceptions

#SS(0) if SP or ESP would exceed the stack limit at any point during instruction execution; #PF(fault-code) for a page fault

# HLT -- Halt

OpcodeInstructionClocks DescriptionExample
F4hlt 5 Halthlt

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

None

## Protected Mode Exceptions

HLT is a privileged instruction; #GP(0) if the current privilege level is not 0

None

## Virtual 8086 Mode Exceptions

#GP(0); HLT is a privileged instruction

# IDIV -- Signed Divide

OpcodeInstructionClocks DescriptionExample
F6 /7idivb r/m819 Signed divide AX by r/m byte (AL=Quo, AH=Rem)idivb %dl
idivb (%ebx,1)
idivb m8(%ebx,1)
idivb m8(%ebx,%ebp,1)
F7 /7idivw r/m16,ax27 Signed divide DX:AX by EA word (AX=Quo, DX=Rem)idivw %cx,%ax
idivw (%ebx,1),%ax
idivw (%ebx,2),%ax
idivw (%ebx,%ebp,1),%ax
F7 /7idivl r/m32,eax43 Signed divide EDX:EAX by DWORD byte (EAX=Quo, EDX=Rem)idivl %ecx,%eax
idivl (%ebx,2),%eax
idivl (%ebx,4),%eax
idivl (%ebx,%ebp,1),%eax

## Operation

```

temp := dividend / divisor;
IF temp does not fit in quotient
THEN Interrupt 0;
ELSE
quotient := temp;
remainder := dividend MOD (r/m);
FI;
```

### Notes

Divisions are signed. The divisor is given by the r/m operand. The dividend, quotient, and remainder use implicit registers. Refer to the table under "Description"

## Description

IDIV performs a signed division. The dividend, quotient, and remainder are implicitly allocated to fixed registers. Only the divisor is given as an explicit r/m operand. The type of the divisor determines which registers to use as follows:
```

Size     Divisor    Quotient    Remainder  Dividend
byte     r/m8        AL           AH       AX
word     r/m16       AX           DX       DX:AX
dword    r/m32       EAX          EDX      EDX:EAX
```
If the resulting quotient is too large to fit in the destination, or if the division is 0, an Interrupt 0 is generated. Nonintegral quotients are truncated toward 0. The remainder has the same sign as the dividend and the absolute value of the remainder is always less than the absolute value of the divisor.

## Flags Affected

OF, SF, ZF, AR, PF, CF are undefined.

## Protected Mode Exceptions

Interrupt 0 if the quotient is too large to fit in the designated register (AL or AX), or if the divisor is 0; #GP (0) for an illegal memory operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page fault

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

OpcodeInstructionClocks DescriptionExample
F6 /5imulb r/m89-14/12-17 AX= AL * r/m byteimulb %dl
imulb (%ebx,1)
imulb m8(%ebx,1)
imulb m8(%ebx,%ebp,1)
F7 /5imulw r/m169-22/12-25 DX:AX := AX * r/m wordimulw %cx
imulw (%ebx,1)
imulw (%ebx,2)
imulw (%ebx,%ebp,1)
F7 /5imull r/m329-38/12-41 EDX:EAX := EAX * r/m dwordimull %ecx
imull (%ebx,2)
imull (%ebx,4)
imull (%ebx,%ebp,1)
0F AF /rimulw r/m16,r169-22/12-25 word register := word register * r/m wordimulw %cx,%bx
imulw (%ebx,1),%bx
imulw (%ebx,2),%bx
imulw (%ebx,%ebp,1),%bx
0F AF /rimull r/m32,r329-38/12-41 dword register := dword register * r/m dwordimull %ecx,%ebx
imull (%ebx,2),%ebx
imull (%ebx,4),%ebx
imull (%ebx,%ebp,1),%ebx
6B /r ibimulw r/m16,r169-14/12-17 word register := r/m16 * sign-extended immediate byteimulw %cx,%bx
imulw (%ebx,1),%bx
imulw (%ebx,2),%bx
imulw (%ebx,%ebp,1),%bx
6B /r ibimull r/m32,r329-14/12-17 dword register := r/m32 * sign-extended immediate byteimull %ecx,%ebx
imull (%ebx,2),%ebx
imull (%ebx,4),%ebx
imull (%ebx,%ebp,1),%ebx
6B /r ibimulw imm8,r169-14/12-17 word register := word register * sign-extended immediate byteimulw \$0x7f,%bx
6B /r ibimull imm8,r329-14/12-17 dword register := dword register * sign-extended immediate byteimull \$0x7f,%ebx
69 /r iwimulw r/m16,r169-22/12-25 word register := r/m16 * immediate wordimulw %cx,%bx
imulw (%ebx,1),%bx
imulw (%ebx,2),%bx
imulw (%ebx,%ebp,1),%bx
69 /r idimull r/m32,r329-38/12-41 dword register := r/m32 * immediate dwordimull %ecx,%ebx
imull (%ebx,2),%ebx
imull (%ebx,4),%ebx
imull (%ebx,%ebp,1),%ebx
69 /r iwimulw imm16,r169-22/12-25 word register := r/m16 * immediate wordimulw \$0x7fff,%bx
69 /r idimull imm32,r329-38/12-41 dword register := r/m32 * immediate dwordimull \$0x7fffffff,%ebx

### Notes

The 80386 uses an early-out multiply algorithm. The actual number of clocks depends on the position of the most significant bit in the optimizing multiplier, shown underlined above. The optimization occurs for positive and negative values. Because of the early-out algorithm, clock counts given are minimum to maximum. To calculate the actual clocks, use the following formula:
```

Actual clock = if m <> 0 then max(ceiling(log{2}(m)), 3) + 6 clocks
Actual clock = if m = 0 then 9 clocks
(where m is the multiplier)
```
Add three clocks if the multiplier is a memory operand.

## Operation

```

result := multiplicand * multiplier;
```

## Description

IMUL performs signed multiplication. Some forms of the instruction use implicit register operands. The operand combinations for all forms of the instruction are shown in the "

## Description

" column above.

IMUL clears the overflow and carry flags under the following conditions:

```

Instruction Form    Condition for Clearing CF and OF
r/m8                AL := sign-extend of AL to 16 bits
r/m16               AX := sign-extend of AX to 32 bits
r/m32               EDX:EAX := sign-extend of EAX to 32 bits
r16,r/m16           Result exactly fits within r16
r/32,r/m32          Result exactly fits within r32
r16,r/m16,imm16     Result exactly fits within r16
r32,r/m32,imm32     Result exactly fits within r32
```

## Flags Affected

OF and CF as described above; SF, ZF, AF, and PF are undefined

## Protected Mode Exceptions

#GP(0) for an illegal memory operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page fault

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

OpcodeInstructionClocks DescriptionExample
E4 ibinb imm8,al12,pm=6*/26** Input byte from immediate port into ALinb \$0x7f,%al
E5 ibinw imm8,ax12,pm=6*/26** Input word from immediate port into AXinw \$0x7f,%ax
E5 ibinl imm8,eax12,pm=6*/26** Input dword from immediate port into EAXinl \$0x7f,%eax
ECinb dx,al13,pm=7*/27** Input byte from port DX into ALinb %dx,%al
EDinw dx,ax13,pm=7*/27** Input word from port DX into AXinw %dx,%ax
EDinl dx,eax13,pm=7*/27** Input dword from port DX into EAXinl %dx,%eax

### Notes

```

*If CPL <= IOPL
**If CPL > IOPL or if in virtual 8086 mode
```

## Operation

```

IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
IF NOT I-O-Permission (SRC, width(SRC))
THEN #GP(0);
FI;
FI;
```

## Description

IN transfers a data byte or data word from the port numbered by the second operand into the register (AL, AX, or EAX) specified by the first operand. Access any port from 0 to 65535 by placing the port number in the DX register and using an IN instruction with DX as the second parameter. These I/O instructions can be shortened by using an 8-bit port I/O in the instruction. The upper eight bits of the port address will be 0 when 8-bit port I/O is used.

None

## Protected Mode Exceptions

#GP(0) if the current privilege level is larger (has less privilege) than IOPL and any of the corresponding I/O permission bits in TSS equals 1

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

OpcodeInstructionClocks DescriptionExample
FE /0incb r/m8 Increment r/m byte by 1incb %dl
incb (%ebx,1)
incb m8(%ebx,1)
incb m8(%ebx,%ebp,1)
FF /0incw r/m16 Increment r/m word by 1incw %cx
incw (%ebx,1)
incw (%ebx,2)
incw (%ebx,%ebp,1)
FF /6incl r/m32 Increment r/m dword by 1incl %ecx
incl (%ebx,2)
incl (%ebx,4)
incl (%ebx,%ebp,1)
40 + rwincw r16 Increment word register by 1incw %bx
40 + rdincl r32 Increment dword register by 1incl %ebx

## 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

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

OpcodeInstructionClocks DescriptionExample
6Cinsb 15,pm=9*/29** Input byte from port DX into ES:(E)DIinsb
6Dinsw 15,pm=9*/29** Input word from port DX into ES:(E)DIinsw
6Dinsl 15,pm=9*/29** Input dword from port DX into ES:(E)DIinsl

### Notes

```

*If CPL <= IOPL
**If CPL > IOPL or if in virtual 8086 mode
```

## Operation

```

THEN use DI for dest-index;
ELSE (* AddressSize = 32 *)
use EDI for dest-index;
FI;
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
IF NOT I-O-Permission (SRC, width(SRC))
THEN #GP(0);
FI;
FI;
IF byte type of instruction
THEN
ES:[dest-index] := [DX]; (* Reads byte at DX from I/O address space *)
IF DF = 0 THEN IncDec := 1 ELSE IncDec := -1; FI;
FI;
IF OperandSize = 16
THEN
ES:[dest-index] := [DX]; (* Reads word at DX from I/O address space *)
IF DF = 0 THEN IncDec := 2 ELSE IncDec := -2; FI;
FI;
IF OperandSize = 32
THEN
ES:[dest-index] := [DX]; (* Reads dword at DX from I/O address space *)
IF DF = 0 THEN IncDec := 4 ELSE IncDec := -4; FI;
FI;
dest-index := dest-index + IncDec;
```

## Description

INS transfers data from the input port numbered by the DX register to the memory byte or word at ES:dest-index. The memory operand must be addressable from ES; no segment override is possible. The destination register is DI if the address-size attribute of the instruction is 16 bits, or EDI if the address-size attribute is 32 bits.

INS does not allow the specification of the port number as an immediate value. The port must be addressed through the DX register value. Load the correct value into DX before executing the INS instruction.

The destination address is determined by the contents of the destination index register. Load the correct index into the destination index register before executing INS.

After the transfer is made, DI or EDI advances automatically. If the direction flag is 0 (CLD was executed), DI or EDI increments; if the direction flag is 1 (STD was executed), DI or EDI decrements. DI increments or decrements by 1 if a byte is input, by 2 if a word is input, or by 4 if a doubleword is input.

INSB, INSW and INSD are synonyms of the byte, word, and doubleword INS instructions. INS can be preceded by the REP prefix for block input of CX bytes or words. Refer to the REP instruction for details of this operation.

None

## Protected Mode Exceptions

#GP(0) if CPL is numerically greater than IOPL and any of the corresponding I/O permission bits in TSS equals 1; #GP(0) if the destination is in a nonwritable segment; #GP(0) for an illegal memory operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page fault

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

OpcodeInstructionClocks DescriptionExample
CC 33 Interrupt 3--trap to debugger
CC pm=59 Interrupt 3--Protected Mode, same privilege
CC pm=99 Interrupt 3--Protected Mode, more privilege
CC pm=119 Interrupt 3--from V86 mode to PL 0
CC ts Interrupt 3--Protected Mode, via task gate
CD ibint imm837 Interrupt numbered by immediate byteint \$0x7f
CD ibint imm8pm=59 Interrupt--Protected Mode, same privilegeint \$0x7f
CD ibint imm8pm=99 Interrupt--Protected Mode, more privilegeint \$0x7f
CD ibint imm8pm=119 Interrupt--from V86 mode to PL 0int \$0x7f
CD ibint imm8ts Interrupt--Protected Mode, via task gateint \$0x7f
CEinto Fail:3,pm=3 into
CEinto pm=59 Interrupt 4--Protected Mode, same privilegeinto
CEinto pm=99 Interrupt 4--Protected Mode, more privilegeinto
CEinto pm=119 Interrupt 4--from V86 mode to PL 0into
CEinto ts Interrupt 4--Protected Mode, via task gateinto

### Note

Approximate values of ts are given by the following table:
```

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
ELSE GOTO PROTECTED-MODE;
FI;

Push (FLAGS);
IF = 0; (* Clear interrupt flag *)
TF = 0; (* Clear trap flag *)
Push(CS);
Push(IP);
(* No error codes are pushed *)
CS := IDT[Interrupt number * 4].selector;
IP := IDT[Interrupt number * 4].offset;

PROTECTED-MODE:
Interrupt vector must be within IDT table limits,
else #GP(vector number * 8+2+EXT);
Descriptor AR byte must indicate interrupt gate, trap gate, or task gate,
else #GP(vector number * 8+2+EXT);
IF software interrupt (* i.e. caused by INT n, INT 3, or INTO *)
THEN
IF gate descriptor DPL < CPL
THEN #GP(vector number * 8+2+EXT);
FI;
FI;
Gate must be present, else #NP(vector number * 8+2+EXT);
IF trap gate OR interrupt gate
THEN GOTO TRAP-GATE-OR-INTERRUPT-GATE;
FI;

TRAP-GATE-OR-INTERRUPT-GATE:
Examine CS selector and descriptor given in the gate descriptor;
Selector must be non-null, else #GP (EXT);
Selector must be within its descriptor table limits
ELSE #GP(selector+EXT);
Descriptor AR byte must indicate code segment
ELSE #GP(selector + EXT);
Segment must be present, else #NP(selector+EXT);
IF code segment is non-conforming AND DPL < CPL
THEN GOTO INTERRUPT-TO-INNER-PRIVILEGE;
ELSE
IF code segment is conforming OR code segment DPL = CPL
THEN GOTO INTERRUPT-TO-SAME-PRIVILEGE-LEVEL;
ELSE #GP(CS selector + EXT);
FI;
FI;

INTERRUPT-TO-INNER-PRIVILEGE:
Check selector and descriptor for new stack in current TSS;
Selector must be non-null, else #GP(EXT);
Selector index must be within its descriptor table limits
ELSE #TS(SS selector+EXT);
Selector's RPL must equal DPL of code segment, else #TS(SS
selector+EXT);
Stack segment DPL must equal DPL of code segment, else #TS(SS
selector+EXT);
Descriptor must indicate writable data segment, else #TS(SS
selector+EXT);
Segment must be present, else #SS(SS selector+EXT);
IF 32-bit gate
THEN New stack must have room for 20 bytes else #SS(0)
ELSE New stack must have room for 10 bytes else #SS(0)
FI;
Instruction pointer must be within CS segment boundaries else #GP(0);
Load new SS and eSP value from TSS;
IF 32-bit gate
THEN CS:EIP := selector:offset from gate;
ELSE CS:IP := selector:offset from gate;
FI;
Load CS descriptor into invisible portion of CS register;
Load SS descriptor into invisible portion of SS register;
IF 32-bit gate
THEN
Push (long pointer to old stack) (* 3 words padded to 4 *);
Push (EFLAGS);
Push (long pointer to return location) (* 3 words padded to 4*);
ELSE
Push (long pointer to old stack) (* 2 words *);
Push (FLAGS);
Push (long pointer to return location) (* 2 words *);
FI;
Set CPL to new code segment DPL;
Set RPL of CS to CPL;
IF interrupt gate THEN IF = 0 (* interrupt flag to 0 (disabled) *); FI;
TF := 0;
NT := 0;

INTERRUPT-FROM-V86-MODE:
TempEFlags := EFLAGS;
VM := 0;
TF := 0;
IF service through Interrupt Gate THEN IF = 0;
TempSS := SS;
TempESP := ESP;
SS := TSS.SS0; (* Change to level 0 stack segment *)
ESP := TSS.ESP0; (* Change to level 0 stack pointer *)
Push(GS); (* padded to two words *)
Push(FS); (* padded to two words *)
Push(DS); (* padded to two words *)
Push(ES); (* padded to two words *)
GS := 0;
FS := 0;
DS := 0;
ES := 0;
Push(TempSS); (* padded to two words *)
Push(TempESP);
Push(TempEFlags);
Push(CS); (* padded to two words *)
Push(EIP);
CS:EIP := selector:offset from interrupt gate;
(* Starts execution of new routine in 80386 Protected Mode *)

INTERRUPT-TO-SAME-PRIVILEGE-LEVEL:
IF 32-bit gate
THEN Current stack limits must allow pushing 10 bytes, else #SS(0);
ELSE Current stack limits must allow pushing 6 bytes, else #SS(0);
FI;
IF interrupt was caused by exception with error code
THEN Stack limits must allow push of two more bytes;
ELSE #SS(0);
FI;
Instruction pointer must be in CS limit, else #GP(0);
IF 32-bit gate
THEN
Push (EFLAGS);
Push (long pointer to return location); (* 3 words padded to 4 *)
CS:EIP := selector:offset from gate;
ELSE (* 16-bit gate *)
Push (FLAGS);
Push (long pointer to return location); (* 2 words *)
CS:IP := selector:offset from gate;
FI;
Load CS descriptor into invisible portion of CS register;
Set the RPL field of CS to CPL;
Push (error code); (* if any *)
IF interrupt gate THEN IF = 0; FI;
TF := 0;
NT := 0;

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);
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.

None

## Protected Mode Exceptions

#GP, #NP, #SS, and #TS as indicated under "

## Operation

" above

None; if the SP or ESP = 1, 3, or 5 before executing INT or INTO, the 80386 will shut down due to insufficient stack space

## Virtual 8086 Mode Exceptions

#GP(0) fault if IOPL is less than 3, for INT only, to permit emulation; Interrupt 3 (0CCH) generates Interrupt 3; INTO generates Interrupt 4 if the overflow flag equals 1

# IRET/IRETD -- Interrupt Return

OpcodeInstructionClocks DescriptionExample
CFiret 22,pm=38 Interrupt return (far return and pop flags)iret
CFiret ts Interrupt return, different task (NT = 1)iret
CFiretl 22,pm=38 Interrupt return (far return and pop flags)iretl
CFiretl ts Interrupt return, different task (NT = 1)iretl
NoteValues of ts are given by the following table:
```

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
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
ELSE
IF VM = 1 in flags image on stack
THEN GO TO STACK-RETURN-TO-V86;
ELSE GOTO STACK-RETURN;
FI;
FI;
FI;
FI;STACK-RETURN-TO-V86: (* Interrupted procedure was in V86 mode *)
IF return CS selector RPL < > 3
THEN #GP(Return selector);
FI;
IF top 36 bytes of stack not within limits
THEN #SS(0);
FI;
Examine return CS selector and associated descriptor:
IF selector is null, THEN #GP(0); FI;
IF selector index not within its descriptor table limits;
THEN #GP(Return selector);
FI;
IF AR byte does not indicate code segment
THEN #GP(Return selector);
FI;
IF code segment DPL not = 3;
THEN #GP(Return selector);
FI;
IF code segment not present
THEN #NP(Return selector);
FI;

Examine return SS selector and associated descriptor:
IF selector is null THEN #GP(0); FI;
IF selector index not within its descriptor table limits
THEN #GP(SS selector);
FI;
IF selector RPL not = RPL of return CS selector
THEN #GP(SS selector);
FI;
IF AR byte does not indicate a writable data segment
THEN #GP(SS selector);
FI;
IF stack segment DPL not = RPL of return CS selector
THEN #GP(SS selector);
FI;
IF SS not present
THEN #NP(SS selector);
FI;

IF instruction pointer not within code segment limit  THEN #GP(0);
FI;
EFLAGS := SS:[eSP + 8]; (* Sets VM in interrupted routine *)
EIP := Pop();
CS := Pop(); (* CS behaves as in 8086, due to VM = 1 *)
ES := Pop(); (* pop 2 words; throw away high-order word *)
DS := Pop(); (* pop 2 words; throw away high-order word *)
FS := Pop(); (* pop 2 words; throw away high-order word *)
GS := Pop(); (* pop 2 words; throw away high-order word *)
IF CS.RPL > CPL
THEN
TempESP := Pop();
TempSS := Pop();
SS:ESP := TempSS:TempESP;
FI;

(* Resume execution in Virtual 8086 mode *)

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);
Mark the task just abandoned as NOT BUSY;
Instruction pointer must be within code segment limit ELSE #GP(0);

STACK-RETURN:
IF OperandSize=32
THEN Third word on stack must be within stack limits, else #SS(0);
ELSE Second word on stack must be within stack limits, else #SS(0);
FI;
Return CS selector RPL must be >= CPL, else #GP(Return selector);
IF return selector RPL = CPL
THEN GOTO RETURN-SAME-LEVEL;
ELSE GOTO RETURN-OUTER-LEVEL;
FI;

RETURN-SAME-LEVEL:
IF OperandSize=32
THEN
Top 12 bytes on stack must be within limits, else #SS(0);
Return CS selector (at eSP+4) must be non-null, else #GP(0);
ELSE
Top 6 bytes on stack must be within limits, else #SS(0);
Return CS selector (at eSP+2) must be non-null, else #GP(0);
FI;
Selector index must be within its descriptor table limits, else #GP
(Return selector);
AR byte must indicate code segment, else #GP(Return selector);
IF non-conforming
THEN code segment DPL must = CPL;
ELSE #GP(Return selector);
FI;
IF conforming
THEN code segment DPL must be <= CPL, else #GP(Return selector);
Segment must be present, else #NP(Return selector);
Instruction pointer must be within code segment boundaries, else #GP(0);
FI;
IF OperandSize=32
THEN
Load CS-register with new code segment descriptor;
Load EFLAGS with third doubleword from stack;
Increment eSP by 12;
ELSE
Load CS-register with new code segment descriptor;
Load FLAGS with third word on stack;
Increment eSP by 6;
FI;

RETURN-OUTER-LEVEL:
IF OperandSize=32
THEN Top 20 bytes on stack must be within limits, else #SS(0);
ELSE Top 10 bytes on stack must be within limits, else #SS(0);
FI;
Examine return CS selector and associated descriptor:
Selector must be non-null, else #GP(0);
Selector index must be within its descriptor table limits;
ELSE #GP(Return selector);
AR byte must indicate code segment, else #GP(Return selector);
IF non-conforming
THEN code segment DPL must = CS selector RPL;
ELSE #GP(Return selector);
FI;
IF conforming
THEN code segment DPL must be > CPL;
ELSE #GP(Return selector);
FI;
Segment must be present, else #NP(Return selector);
Examine return SS selector and associated descriptor:
Selector must be non-null, else #GP(0);
Selector index must be within its descriptor table limits
ELSE #GP(SS selector);
Selector RPL must equal the RPL of the return CS selector
ELSE #GP(SS selector);
AR byte must indicate a writable data segment, else #GP(SS selector);
Stack segment DPL must equal the RPL of the return CS selector
ELSE #GP(SS selector);
SS must be present, else #NP(SS selector);

Instruction pointer must be within code segment limit ELSE #GP(0);
IF OperandSize=32
THEN
Load EFLAGS with values at (eSP+8);
ELSE
Load FLAGS with values at (eSP+4);
FI;
Set CPL to the RPL of the return CS selector;
Load the CS register with the CS descriptor;
Load the SS register with the SS descriptor;
FOR each of ES, FS, GS, and DS
DO;
IF the current value of the register is not valid for the outer level;
THEN zero the register and clear the valid flag;
FI;
To be valid, the register setting must satisfy the following
properties:
Selector index must be within descriptor table limits;
AR byte must indicate data or readable code segment;
IF segment is data or non-conforming code,
THEN DPL must be >= CPL, or DPL must be >= RPL;
OD;
```

## Description

In Real Address Mode, IRET pops the instruction pointer, CS, and the flags register from the stack and resumes the interrupted routine.

In Protected Mode, the action of IRET depends on the setting of the nested task flag (NT) bit in the flag register. When popping the new flag image from the stack, the IOPL bits in the flag register are changed only when CPL equals 0.

If NT equals 0, IRET returns from an interrupt procedure without a task switch. The code returned to must be equally or less privileged than the interrupt routine (as indicated by the RPL bits of the CS selector popped from the stack). If the destination code is less privileged, IRET also pops the stack pointer and SS from the stack.

If NT equals 1, IRET reverses the operation of a CALL or INT that caused a task switch. The updated state of the task executing IRET is saved in its task state segment. If the task is reentered later, the code that follows IRET is executed.

## Flags Affected

All; the flags register is popped from stack

## Protected Mode Exceptions

#GP, #NP, or #SS, as indicated under "

## Operation

" above

Interrupt 13 if any part of the operand being popped lies beyond address 0FFFFH

## Virtual 8086 Mode Exceptions

#GP(0) fault if IOPL is less than 3, to permit emulation

# Jcc -- Jump if Condition is Met

OpcodeInstructionClocks DescriptionExample
77 cbja rel87+m,3 Jump short if above (CF=0 and ZF=0)ja rel8_0
73 cbjae rel87+m,3 Jump short if above or equal (CF=0)jae rel8_1
72 cbjb rel87+m,3 Jump short if below (CF=1)jb rel8_2
76 cbjbe rel87+m,3 Jump short if below or equal (CF=1 or ZF=1)jbe rel8_3
72 cbjc rel87+m,3 Jump short if carry (CF=1)jc rel8_4
E3 cbjcxz rel89+m,5 Jump short if CX register is 0jcxz rel8_5
E3 cbjecxz rel89+m,5 Jump short if ECX register is 0jecxz rel8_6
74 cbje rel87+m,3 Jump short if equal (ZF=1)je rel8_7
74 cbjz rel87+m,3 Jump short if 0 (ZF=1)jz rel8_8
7F cbjg rel87+m,3 Jump short if greater (ZF=0 and SF=OF)jg rel8_9
7D cbjge rel87+m,3 Jump short if greater or equal (SF=OF)jge rel8_10
7C cbjl rel87+m,3 Jump short if less (SF<jl rel8_11
7E cbjle rel87+m,3 Jump short if less or equal (ZF=1 and SF<jle rel8_12
76 cbjna rel87+m,3 Jump short if not above (CF=1 or ZF=1)jna rel8_13
72 cbjnae rel87+m,3 Jump short if not above or equal (CF=1)jnae rel8_14
73 cbjnb rel87+m,3 Jump short if not below (CF=0)jnb rel8_15
77 cbjnbe rel87+m,3 Jump short if not below or equal (CF=0 and ZF=0)jnbe rel8_16
73 cbjnc rel87+m,3 Jump short if not carry (CF=0)jnc rel8_17
75 cbjne rel87+m,3 Jump short if not equal (ZF=0)jne rel8_18
7E cbjng rel87+m,3 Jump short if not greater (ZF=1 or SF<jng rel8_19
7C cbjnge rel87+m,3 Jump short if not greater or equal (SF<jnge rel8_20
7D cbjnl rel87+m,3 Jump short if not less (SF=OF)jnl rel8_21
7F cbjnle rel87+m,3 Jump short if not less or equal (ZF=0 and SF=OF)jnle rel8_22
71 cbjno rel87+m,3 Jump short if not overflow (OF=0)jno rel8_23
7B cbjnp rel87+m,3 Jump short if not parity (PF=0)jnp rel8_24
79 cbjns rel87+m,3 Jump short if not sign (SF=0)jns rel8_25
75 cbjnz rel87+m,3 Jump short if not zero (ZF=0)jnz rel8_26
70 cbjo rel87+m,3 Jump short if overflow (OF=1)jo rel8_27
7A cbjp rel87+m,3 Jump short if parity (PF=1)jp rel8_28
7A cbjpe rel87+m,3 Jump short if parity even (PF=1)jpe rel8_29
7B cbjpo rel87+m,3 Jump short if parity odd (PF=0)jpo rel8_30
78 cbjs rel87+m,3 Jump short if sign (SF=1)js rel8_31
74 cbjz rel87+m,3 Jump short if zero (ZF = 1)jz rel8_32
0F 87 cw/cdja rel16/327+m,3 Jump near if above (CF=0 and ZF=0)ja rel16
0F 83 cw/cdjae rel16/327+m,3 Jump near if above or equal (CF=0)jae rel16
0F 82 cw/cdjb rel16/327+m,3 Jump near if below (CF=1)jb rel16
0F 86 cw/cdjbe rel16/327+m,3 Jump near if below or equal (CF=1 or ZF=1)jbe rel16
0F 82 cw/cdjc rel16/327+m,3 Jump near if carry (CF=1)jc rel16
0F 84 cw/cdje rel16/327+m,3 Jump near if equal (ZF=1)je rel16
0F 84 cw/cdjz rel16/327+m,3 Jump near if 0 (ZF=1)jz rel16
0F 8F cw/cdjg rel16/327+m,3 Jump near if greater (ZF=0 and SF=OF)jg rel16
0F 8D cw/cdjge rel16/327+m,3 Jump near if greater or equal (SF=OF)jge rel16
0F 8C cw/cdjl rel16/327+m,3 Jump near if less (SF<jl rel16
0F 8E cw/cdjle rel16/327+m,3 Jump near if less or equal (ZF=1 and SF<jle rel16
0F 86 cw/cdjna rel16/327+m,3 Jump near if not above (CF=1 or ZF=1)jna rel16
0F 82 cw/cdjnae rel16/327+m,3 Jump near if not above or equal (CF=1)jnae rel16
0F 83 cw/cdjnb rel16/327+m,3 Jump near if not below (CF=0)jnb rel16
0F 87 cw/cdjnbe rel16/327+m,3 Jump near if not below or equal (CF=0 and ZF=0)jnbe rel16
0F 83 cw/cdjnc rel16/327+m,3 Jump near if not carry (CF=0)jnc rel16
0F 85 cw/cdjne rel16/327+m,3 Jump near if not equal (ZF=0)jne rel16
0F 8E cw/cdjng rel16/327+m,3 Jump near if not greater (ZF=1 or SF<jng rel16
0F 8C cw/cdjnge rel16/327+m,3 Jump near if not greater or equal (SF<jnge rel16
0F 8D cw/cdjnl rel16/327+m,3 Jump near if not less (SF=OF)jnl rel16
0F 8F cw/cdjnle rel16/327+m,3 Jump near if not less or equal (ZF=0 and SF=OF)jnle rel16
0F 81 cw/cdjno rel16/327+m,3 Jump near if not overflow (OF=0)jno rel16
0F 8B cw/cdjnp rel16/327+m,3 Jump near if not parity (PF=0)jnp rel16
0F 89 cw/cdjns rel16/327+m,3 Jump near if not sign (SF=0)jns rel16
0F 85 cw/cdjnz rel16/327+m,3 Jump near if not zero (ZF=0)jnz rel16
0F 80 cw/cdjo rel16/327+m,3 Jump near if overflow (OF=1)jo rel16
0F 8A cw/cdjp rel16/327+m,3 Jump near if parity (PF=1)jp rel16
0F 8A cw/cdjpe rel16/327+m,3 Jump near if parity even (PF=1)jpe rel16
0F 8B cw/cdjpo rel16/327+m,3 Jump near if parity odd (PF=0)jpo rel16
0F 88 cw/cdjs rel16/327+m,3 Jump near if sign (SF=1)js rel16
0F 84 cw/cdjz rel16/327+m,3 Jump near if 0 (ZF=1)jz rel16

### 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;
```
```

JNZ BEYOND;
JMP FARLABEL;
BEYOND:
```
Because there can be several ways to interpret a particular state of the flags, ASM386 provides more than one mnemonic for most of the conditional jump opcodes. For example, if you compared two characters in AX and want to jump if they are equal, use JE; or, if you ANDed AX with a bit field mask and only want to jump if the result is 0, use JZ, a synonym for JE.

JCXZ differs from other conditional jumps because it tests the contents of the CX or ECX register for 0, not the flags. JCXZ is useful at the beginning of a conditional loop that terminates with a conditional loop instruction (such as LOOPNE TARGET LABEL). The JCXZ prevents entering the loop with CX or ECX equal to zero, which would cause the loop to execute 64K or 32G times instead of zero times.

None

## Protected Mode Exceptions

#GP(0) if the offset jumped to is beyond the limits of the code segment

None

None

# JMP -- Jump

OpcodeInstructionClocks DescriptionExample
EB cbjmp rel87+m Jump shortjmp rel8_33
E9 cwjmp rel167+m Jump near, displacement relative to next instructionjmp rel16
FF /4jmpw r/m167+m/10+m Jump near indirectjmpw *%cx
jmpw *(%ebx,1)
jmpw (%ebx,2)
jmpw (%ebx,%ebp,1)
EA cdjmpw ptr16:1612+m,pm=27+m Jump intersegment, 4-byte immediate addressjmpw *(%ebx,1)
EA cdjmpw ptr16:16ts Jump via task state segmentjmpw *(%ebx,1)
EA cdjmpw ptr16:16ts Jump via task gatejmpw *(%ebx,1)
FF /5jmpw m16:1643+m,pm=31+m Jump r/m16:16 indirect and intersegmentjmp tocall
FF /5jmpw m16:165 + ts Jump via task state segmentjmp tocall
FF /5jmpw m16:165 + ts Jump via task gatejmp tocall
E9 cdjmp rel327+m Jump near, displacement relative to next instructionjmp rel32
FF /4jmpl r/m327+m,10+m Jump near, indirectjmpl *%ecx
jmpl *(%ebx,2)
jmpl (%ebx,4)
jmpl (%ebx,%ebp,1)
EA cpjmpw ptr16:3212+m,pm=27+m Jump intersegment, 6-byte immediate addressjmpw *(%ebx,1)
EA cpjmpw ptr16:32ts Jump via task state segmentjmpw *(%ebx,1)
EA cpjmpw ptr16:32ts Jump via task gatejmpw *(%ebx,1)
FF /5jmpw m16:3243+m,pm=31+m Jump intersegment, address at r/m dwordjmp tocall
FF /5jmpw m16:325 + ts Jump via task state segmentjmp tocall
FF /5jmpw m16:325 + ts Jump via task gatejmp tocall

### Note

Values of ts are given by the following table:
```

386 TSS       386 TASK       286 TSS
VM = 0        VM = 1

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;
ELSE #GP(selector); (* illegal AR byte in descriptor *)
FI;

CONFORMING-CODE-SEGMENT:
Descriptor DPL must be <= CPL ELSE #GP(selector);
Segment must be present ELSE #NP(selector);
Instruction pointer must be within code-segment limit ELSE #GP(0);
IF OperandSize = 32
THEN Load CS:EIP from destination pointer;
ELSE Load CS:IP from destination pointer;
FI;
Load CS register with new segment descriptor;

NONCONFORMING-CODE-SEGMENT:
RPL of destination selector must be <= CPL ELSE #GP(selector);
Descriptor DPL must be = CPL ELSE #GP(selector);
Segment must be present ELSE # NP(selector);
Instruction pointer must be within code-segment limit ELSE #GP(0);
IF OperandSize = 32
THEN Load CS:EIP from destination pointer;
ELSE Load CS:IP from destination pointer;
FI;
Load CS register with new segment descriptor;
Set RPL field of CS register to CPL;

CALL-GATE:
Descriptor DPL must be >= CPL ELSE #GP(gate selector);
Descriptor DPL must be >= gate selector RPL ELSE #GP(gate selector);
Gate must be present ELSE #NP(gate selector);
Examine selector to code segment given in call gate descriptor:
Selector must not be null ELSE #GP(0);
Selector must be within its descriptor table limits ELSE
#GP(CS selector);
Descriptor AR byte must indicate code segment
ELSE #GP(CS selector);
IF non-conforming
THEN code-segment descriptor, DPL must = CPL
ELSE #GP(CS selector);
FI;
IF conforming
THEN code-segment descriptor DPL must be <= CPL;
ELSE #GP(CS selector);
Code segment must be present ELSE #NP(CS selector);
Instruction pointer must be within code-segment limit ELSE #GP(0);
IF OperandSize = 32
THEN Load CS:EIP from call gate;
ELSE Load CS:IP from call gate;
FI;
Load CS register with new code-segment descriptor;
Set RPL of CS to CPL

Gate descriptor DPL must be >= CPL ELSE #GP(gate selector);
Gate descriptor DPL must be >= gate selector RPL ELSE #GP(gate
selector);
Task Gate must be present ELSE #NP(gate selector);
Examine selector to TSS, given in Task Gate descriptor:
Must specify global in the local/global bit ELSE #GP(TSS selector);
Index must be within GDT limits ELSE #GP(TSS selector);
Descriptor AR byte must specify available TSS (bottom bits 00001);
ELSE #GP(TSS selector);
Task State Segment must be present ELSE #NP(TSS selector);
Instruction pointer must be within code-segment limit ELSE #GP(0);

TSS DPL must be >= CPL ELSE #GP(TSS selector);
TSS DPL must be >= TSS selector RPL ELSE #GP(TSS selector);
Descriptor AR byte must specify available TSS (bottom bits 00001)
ELSE #GP(TSS selector);
Task State Segment must be present ELSE #NP(TSS selector);
Instruction pointer must be within code-segment limit ELSE #GP(0);
```

## Description

The JMP instruction transfers control to a different point in the instruction stream without recording return information.

The action of the various forms of the instruction are shown below.

Jumps with destinations of type r/m16, r/m32, rel16, and rel32 are near jumps and do not involve changing the segment register value.

The JMP rel16 and JMP rel32 forms of the instruction add an offset to the address of the instruction following the JMP to determine the destination. The rel16 form is used when the instruction's operand-size attribute is 16 bits (segment size attribute 16 only); rel32 is used when the operand-size attribute is 32 bits (segment size attribute 32 only). The result is stored in the 32-bit EIP register. With rel16, the upper 16 bits of EIP are cleared, which results in an offset whose value does not exceed 16 bits.

JMP r/m16 and JMP r/m32 specifies a register or memory location from which the absolute offset from the procedure is fetched. The offset fetched from r/m is 32 bits for an operand-size attribute of 32 bits (r/m32), or 16 bits for an operand-size attribute of 16 bits (r/m16).

The JMP ptr16:16 and ptr16:32 forms of the instruction use a four-byte or six-byte operand as a long pointer to the destination. The JMP and forms fetch the long pointer from the memory location specified (indirection). In Real Address Mode or Virtual 8086 Mode, the long pointer provides 16 bits for the CS register and 16 or 32 bits for the EIP register (depending on the operand-size attribute). In Protected Mode, both long pointer forms consult the Access Rights (AR) byte in the descriptor indexed by the selector part of the long pointer.

Depending on the value of the AR byte, the jump will perform one of the following types of control transfers:

• A jump to a code segment at the same privilege level
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.

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

OpcodeInstructionClocks DescriptionExample
9Flahf 2 Load: AH := flags SF ZF xx AF xx PF xx CFlahf

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

None

# LAR -- Load Access Rights Byte

OpcodeInstructionClocks DescriptionExample
0F 02 /rlarw r/m16,r16pm=15/16 r16 := r/m16 masked by FF00larw %cx,%bx
larw (%ebx,1),%bx
larw (%ebx,2),%bx
larw (%ebx,%ebp,1),%bx
0F 02 /rlarl r/m32,r32pm=15/16 r32 := r/m32 masked by 00FxFF00larl %ecx,%ebx
larl (%ebx,2),%ebx
larl (%ebx,4),%ebx
larl (%ebx,%ebp,1),%ebx

## Description

The LAR instruction stores a marked form of the second doubleword of the descriptor for the source selector if the selector is visible at the CPL (modified by the selector's RPL) and is a valid descriptor type. The destination register is loaded with the high-order doubleword of the descriptor masked by 00FxFF00, and ZF is set to 1. The x indicates that the four bits corresponding to the upper four bits of the limit are undefined in the value loaded by LAR. If the selector is invisible or of the wrong type, ZF is cleared.

If the 32-bit operand size is specified, the entire 32-bit value is loaded into the 32-bit destination register. If the 16-bit operand size is specified, the lower 16-bits of this value are stored in the 16-bit destination register.

All code and data segment descriptors are valid for LAR.

The valid special segment and gate descriptor types for LAR are given in the following table:

```

Type   Name                     Valid/Invalid

0    Invalid                  Invalid
1    Available 80286 TSS      Valid
2    LDT                      Valid
3    Busy 80286 TSS           Valid
4    80286 call gate          Valid
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

Interrupt 6; LAR is unrecognized in Real Address Mode

## Virtual 8086 Mode Exceptions

Same exceptions as in Real Address Mode

OpcodeInstructionClocks DescriptionExample
8D /rleaw m,r162 Store effective address for m in register r16leaw m,%bx
8D /rleal m,r322 Store effective address for m in register r32leal m,%ebx
8D /rleaw m,r162 Store effective address for m in register r16leaw m,%bx
8D /rleal m,r322 Store effective address for m in register r32leal m,%ebx

## Operation

```

IF OperandSize = 16 AND AddressSize = 16
ELSE
IF OperandSize = 16 AND AddressSize = 32
THEN
ELSE
IF OperandSize = 32 AND AddressSize = 16
THEN
ELSE
IF OperandSize = 32 AND AddressSize = 32
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.
```

None

## Protected Mode Exceptions

#UD if the second operand is a register

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

OpcodeInstructionClocks DescriptionExample
C9leave 4 Set SP to BP, then pop BPleave
C9leave 4 Set ESP to EBP, then pop EBPleave

## Operation

```

THEN
SP := BP;
ELSE (* StackAddrSize = 32 *)
ESP := EBP;
FI;
IF OperandSize = 16
THEN
BP := Pop();
ELSE (* OperandSize = 32 *)
EBP := Pop();
FI;
```

## Description

LEAVE reverses the actions of the ENTER instruction. By copying the frame pointer to the stack pointer, LEAVE releases the stack space used by a procedure for its local variables. The old frame pointer is popped into BP or EBP, restoring the caller's frame. A subsequent RET instruction removes any arguments pushed onto the stack of the exiting procedure.

None

## Protected Mode Exceptions

#SS(0) if BP does not point to a location within the limits of the current stack segment

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

OpcodeInstructionClocks DescriptionExample
0F 01 /2lgdtw m16&3211 Load m into GDTRlgdtw m32
0F 01 /3lidtw m16&3211 Load m into IDTRlidtw m32

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

None

## Protected Mode Exceptions

#GP(0) if the current privilege level is not 0; #UD if the source operand is a register; #GP(0) for an illegal memory operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page fault

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

OpcodeInstructionClocks DescriptionExample
C5 /rldsw m16:16,r167,p=22 Load DS:r16 with pointer from memorylds tocall,%bx
C5 /rldsl m16:32,r327,p=22 Load DS:r32 with pointer from memoryldsl tocall,%ebx
0F B2 /rlssw m16:16,r167,p=22 Load SS:r16 with pointer from memorylss tocall,%bx
0F B2 /rlssl m16:32,r327,p=22 Load SS:r32 with pointer from memorylssl tocall,%ebx
C4 /rlesw m16:16,r167,p=22 Load ES:r16 with pointer from memoryles tocall,%bx
C4 /rlesl m16:32,r327,p=22 Load ES:r32 with pointer from memorylesl tocall,%ebx
0F B4 /rlfsw m16:16,r167,p=25 Load FS:r16 with pointer from memorylfs tocall,%bx
0F B4 /rlfsl m16:32,r327,p=25 Load FS:r32 with pointer from memorylfsl tocall,%ebx
0F B5 /rlgsw m16:16,r167,p=25 Load GS:r16 with pointer from memorylgs tocall,%bx
0F B5 /rlgsl m16:32,r327,p=25 Load GS:r32 with pointer from memorylgsl tocall,%ebx

## 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 selector is null THEN #GP(0); FI;
Selector index must be within its descriptor table limits ELSE
#GP(selector);
Selector's RPL must equal CPL ELSE #GP(selector);
AR byte must indicate a writable data segment ELSE #GP(selector);
DPL in the AR byte must equal CPL ELSE #GP(selector);
Segment must be marked present ELSE #SS(selector);
IF DS, ES, FS, or GS is loaded with non-null selector:
Selector index must be within its descriptor table limits ELSE
#GP(selector);
AR byte must indicate data or readable code segment ELSE
#GP(selector);
IF data or nonconforming code
THEN both the RPL and the CPL must be less than or equal to DPL in
AR byte;
ELSE #GP(selector);
Segment must be marked present ELSE #NP(selector);
Load segment register with selector and RPL bits;
IF DS, ES, FS or GS is loaded with a null selector:
Clear descriptor valid bit;
```

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

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

OpcodeInstructionClocks DescriptionExample
0F 00 /2lldtw r/m1620 Load selector r/m16 into LDTRlldtw %cx
lldtw (%ebx,1)
lldtw (%ebx,2)
lldtw (%ebx,%ebp,1)

```

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.

None

## Protected Mode Exceptions

#GP(0) if the current privilege level is not 0; #GP(selector) if the selector operand does not point into the Global Descriptor Table, or if the entry in the GDT is not a Local Descriptor Table; #NP(selector) if the LDT descriptor is not present; #GP(0) for an illegal memory operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page fault

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

OpcodeInstructionClocks DescriptionExample
0F 01 /6lmsww r/m1610/13 Load r/m16 in machine status wordlmsww %cx
lmsww (%ebx,1)
lmsww (%ebx,2)
lmsww (%ebx,%ebp,1)

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

None

## Protected Mode Exceptions

#GP(0) if the current privilege level is not 0; #GP(0) for an illegal memory operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment; #PF(fault-code) for a page fault

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

OpcodeInstructionClocks DescriptionExample
F0lock 0 Assert LOCK# signal for the next instructionlock

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

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

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

OpcodeInstructionClocks DescriptionExample
AClodsb 5 Load byte DS:[(E)SI] into ALlodsb

## Operation

```

THEN use SI for source-index
ELSE (* AddressSize = 32 *)
use ESI for source-index;
FI;
IF byte type of instruction
THEN
AL := [source-index]; (* byte load *)
IF DF = 0 THEN IncDec := 1 ELSE IncDec := -1; FI;
ELSE
IF OperandSize = 16
THEN
AX := [source-index]; (* word load *)
IF DF = 0 THEN IncDec := 2 ELSE IncDec := -2; FI;
ELSE (* OperandSize = 32 *)
EAX := [source-index]; (* dword load *)
IF DF = 0 THEN IncDec := 4 ELSE IncDec := -4; FI;
FI;
FI;
source-index := source-index + IncDec
```

## Description

LODS loads the AL, AX, or EAX register with the memory byte, word, or doubleword at the location pointed to by the source-index register. After the transfer is made, the source-index register is automatically advanced. If the direction flag is 0 (CLD was executed), the source index increments; if the direction flag is 1 (STD was executed), it decrements. The increment or decrement is 1 if a byte is loaded, 2 if a word is loaded, or 4 if a doubleword is loaded.

If the address-size attribute for this instruction is 16 bits, SI is used for the source-index register; otherwise the address-size attribute is 32 bits, and the ESI register is used. The address of the source data is determined solely by the contents of ESI/SI. Load the correct index value into SI before executing the LODS instruction. LODSB, LODSW, LODSD are synonyms for the byte, word, and doubleword LODS instructions.

LODS can be preceded by the REP prefix; however, LODS is used more typically within a LOOP construct, because further processing of the data moved into EAX, AX, or AL is usually necessary.

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

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

OpcodeInstructionClocks DescriptionExample
E2 cbloop rel811+m DEC countloop rel8_34
E1 cbloope rel811+m DEC countloope rel8_35
E1 cbloopz rel811+m DEC countloopz rel8_36
E0 cbloopne rel811+m DEC countloopne rel8_37
E0 cbloopnz rel811+m DEC countloopnz rel8_38

## Operation

```

IF AddressSize = 16 THEN CountReg is CX ELSE CountReg is ECX; FI;
CountReg := CountReg - 1;
IF instruction <> LOOP
THEN
IF (instruction = LOOPE) OR (instruction = LOOPZ)
THEN BranchCond := (ZF = 1) AND (CountReg <> 0);
FI;
IF (instruction = LOOPNE) OR (instruction = LOOPNZ)
THEN BranchCond := (ZF = 0) AND (CountReg <> 0);
FI;
FI;

IF BranchCond
THEN
IF OperandSize = 16
THEN
IP := IP + SignExtend(rel8);
ELSE (* OperandSize = 32 *)
EIP := EIP + SignExtend(rel8);
FI;
FI;
```

## Description

LOOP decrements the count register without changing any of the flags. Conditions are then checked for the form of LOOP being used. If the conditions are met, a short jump is made to the label given by the operand to LOOP. If the address-size attribute is 16 bits, the CX register is used as the count register; otherwise the ECX register is used. The operand of LOOP must be in the range from 128 (decimal) bytes before the instruction to 127 bytes ahead of the instruction.

The LOOP instructions provide iteration control and combine loop index management with conditional branching. Use the LOOP instruction by loading an unsigned iteration count into the count register, then code the LOOP at the end of a series of instructions to be iterated. The destination of LOOP is a label that points to the beginning of the iteration.

None

## Protected Mode Exceptions

#GP(0) if the offset jumped to is beyond the limits of the current code segment

None

None

# LSL -- Load Segment Limit

OpcodeInstructionClocks DescriptionExample
0F 03 /rlslw r/m16,r16pm=20/21 Load: r16 := segment limit, selector r/m16 (byte granular)lslw %cx,%bx
lslw (%ebx,1),%bx
lslw (%ebx,2),%bx
lslw (%ebx,%ebp,1),%bx
0F 03 /rlsll r/m32,r32pm=20/21 Load: r32 := segment limit, selector r/m32 (byte granular)lsll %ecx,%ebx
lsll (%ebx,2),%ebx
lsll (%ebx,4),%ebx
lsll (%ebx,%ebp,1),%ebx
0F 03 /rlslw r/m16,r16pm=25/26 Load: r16 := segment limit, selector r/m16 (page granular)lslw %cx,%bx
lslw (%ebx,1),%bx
lslw (%ebx,2),%bx
lslw (%ebx,%ebp,1),%bx
0F 03 /rlsll r/m32,r32pm=25/26 Load: r32 := segment limit, selector r/m32 (page granular)lsll %ecx,%ebx
lsll (%ebx,2),%ebx
lsll (%ebx,4),%ebx
lsll (%ebx,%ebp,1),%ebx

## Description

The LSL instruction loads a register with an unscrambled segment limit, and sets ZF to 1, provided that the source selector is visible at the CPL weakened by RPL, and that the descriptor is a type accepted by LSL. Otherwise, ZF is cleared to 0, and the destination register is unchanged. The segment limit is loaded as a byte granular value. If the descriptor has a page granular segment limit, LSL will translate it to a byte limit before loading it in the destination register (shift left 12 the 20-bit "raw" limit from descriptor, then OR with 00000FFFH).

The 32-bit forms of this instruction store the 32-bit byte granular limit in the 16-bit destination register.

Code and data segment descriptors are valid for LSL.

The valid special segment and gate descriptor types for LSL are given in the following table:

```

Type   Name                      Valid/Invalid

0    Invalid                   Invalid
1    Available 80286 TSS       Valid
2    LDT                       Valid
3    Busy 80286 TSS            Valid
4    80286 call gate           Invalid
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

Interrupt 6; LSL is not recognized in Real Address Mode

## Virtual 8086 Mode Exceptions

Same exceptions as in Real Address Mode

OpcodeInstructionClocks DescriptionExample
ltrw (%ebx,1)
ltrw (%ebx,2)
ltrw (%ebx,%ebp,1)

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

None

## Protected Mode Exceptions

#GP(0) for an illegal memory operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS segment; #GP(0) if the current privilege level is not 0; #GP(selector) if the object named by the source selector is not a TSS or is already busy; #NP(selector) if the TSS is marked "not present"; #PF(fault-code) for a page fault

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.

Оставьте свой комментарий !

 Ваше имя: Комментарий: Оба поля являются обязательными

Автор  Комментарий к данной статье