MOV -- Move Data
Opcode | Instruction | Clocks |
Description | Example |
88 /r | movb r8,r/m8 | 2/2 |
Move byte register to r/m byte | movb %bh,%dl
movb %bh,(%ebx,1)
movb %bh,m8(%ebx,1)
movb %bh,m8(%ebx,%ebp,1) |
89 /r | movw r16,r/m16 | 2/2 |
Move word register to r/m word | movw %bx,%cx
movw %bx,(%ebx,1)
movw %bx,(%ebx,2)
movw %bx,(%ebx,%ebp,1) |
89 /r | movl r32,r/m32 | 2/2 |
Move dword register to r/m dword | movl %ebx,%ecx
movl %ebx,(%ebx,2)
movl %ebx,(%ebx,4)
movl %ebx,(%ebx,%ebp,1) |
8A /r | movb r/m8,r8 | 2/4 |
Move r/m byte to byte register | movb %dl,%bh
movb (%ebx,1),%bh
movb m8(%ebx,1),%bh
movb m8(%ebx,%ebp,1),%bh |
8B /r | movw r/m16,r16 | 2/4 |
Move r/m word to word register | movw %cx,%bx
movw (%ebx,1),%bx
movw (%ebx,2),%bx
movw (%ebx,%ebp,1),%bx |
8B /r | movl r/m32,r32 | 2/4 |
Move r/m dword to dword register | movl %ecx,%ebx
movl (%ebx,2),%ebx
movl (%ebx,4),%ebx
movl (%ebx,%ebp,1),%ebx |
8C /r | movw sreg,r/m16 | 2/2 |
Move segment register to r/m word | movw %es,%cx
movw %es,(%ebx,1)
movw %es,(%ebx,2)
movw %es,(%ebx,%ebp,1) |
8D /r | movw r/m16,sreg | 2/5,pm=18/19 |
Move r/m word to segment register | movw %cx,%es
movw (%ebx,1),%es
movw (%ebx,2),%es
movw (%ebx,%ebp,1),%es |
A0 | movb moffs8,al | 4 |
Move byte at (seg:offset) to AL | movb farmem8,%al |
A1 | movw moffs16,ax | 4 |
Move word at (seg:offset) to AX | movw farmem16,%ax |
A1 | movl moffs32,eax | 4 |
Move dword at (seg:offset) to EAX | movl farmem32,%eax |
A2 | movb al,moffs8 | 2 |
Move AL to (seg:offset) | movb %al,farmem8 |
A3 | movw ax,moffs16 | 2 |
Move AX to (seg:offset) | movw %ax,farmem16 |
A3 | movl eax,moffs32 | 2 |
Move EAX to (seg:offset) | movl %eax,farmem32 |
B0 + rb | movb imm8,reg8 | 2 |
Move immediate byte to register | movb $0x7f,%ch |
B8 + rw | movw imm16,reg16 | 2 |
Move immediate word to register | movw $0x7fff,%cx |
B8 + rd | movl imm32,reg32 | 2 |
Move immediate dword to register | movl $0x7fffffff,%ecx |
C6 | movb imm8,r/m8 | 2/2 |
Move immediate byte to r/m byte | movb $0x7f,%dl
movb $0x7f,(%ebx,1)
movb $0x7f,m8(%ebx,1)
movb $0x7f,m8(%ebx,%ebp,1) |
C7 | movw imm16,r/m16 | 2/2 |
Move immediate word to r/m word | movw $0x7fff,%cx
movw $0x7fff,(%ebx,1)
movw $0x7fff,(%ebx,2)
movw $0x7fff,(%ebx,%ebp,1) |
C7 | movl imm32,r/m32 | 2/2 |
Move immediate dword to r/m dword | movl $0x7fffffff,%ecx
movl $0x7fffffff,(%ebx,2)
movl $0x7fffffff,(%ebx,4)
movl $0x7fffffff,(%ebx,%ebp,1) |
Notes moffs8, moffs16, and moffs32
all consist of a simple offset relative to the segment base. The 8, 16,
and 32 refer to the size of the data. The address-size attribute of the
instruction determines the size of the offset, either 16 or 32 bits.
Operation
DEST := SRC;
Description
MOV copies the second operand to the first operand.
If
the destination operand is a segment register (DS, ES, SS, etc.), then
data from a descriptor is also loaded into the register. The data for
the register is obtained from the descriptor table entry for the
selector given. A null selector (values 0000-0003) can be loaded into
DS and ES registers without causing an exception; however, use of DS or
ES causes a #GP(0), and no memory reference occurs. A MOV into SS inhibits all interrupts until after the execution of the next instruction (which is presumably a MOV into eSP).
Loading
a segment register under 80386 Protected Mode results in special checks
and actions, as described in the following listing:
IF SS is loaded;
THEN
IF selector is null THEN #GP(0);
FI;
Selector index must be within its descriptor table limits else
#GP(selector);
Selector's RPL must equal CPL else #GP(selector);
AR byte must indicate a writable data segment else #GP(selector);
DPL in the AR byte must equal CPL else #GP(selector);
Segment must be marked present else #SS(selector);
Load SS with selector;
Load SS with descriptor.
FI;
IF DS, ES, FS or GS is loaded with non-null selector;
THEN
Selector index must be within its descriptor table limits
else #GP(selector);
AR byte must indicate data or readable code segment else
#GP(selector);
IF data or nonconforming code segment
THEN both the RPL and the CPL must be less than or equal to DPL in
AR byte;
ELSE #GP(selector);
FI;
Segment must be marked present else #NP(selector);
Load segment register with selector;
Load segment register with descriptor;
FI;
IF DS, ES, FS or GS is loaded with a null selector;
THEN
Load segment register with selector;
Clear descriptor valid bit;
FI;
Flags Affected
None
Protected Mode Exceptions
#GP, #SS, and #NP if a segment register is being loaded; otherwise,
#GP(0) if the destination is in a nonwritable segment; #GP(0) for an
illegal memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
MOV -- Move to/from Special Registers
Opcode | Instruction | Clocks |
Description | Example |
0F 20 /r | movl cr0/cr2/cr3,r32 | 6 |
Move (control register) to (register) | movl %cr0,%ebx
movl %cr2,%ebx
movl %cr3,%ebx |
0F 22 /r | movl r32,cr0/cr2/cr3 | 10/4/5 |
Move (register) to (control register) | movl %ebx,%cr0
movl %ebx,%cr2
movl %ebx,%cr3 |
0F 21 /r | movl dr0-3,r32 | 22 |
Move (debug register) to (register) | movl %dr0,%ebx |
0F 21 /r | movl dr6/dr7,r32 | 14 |
Move (debug register) to (register) | movl %dr6,%ebx
movl %dr7,%ebx |
0F 23 /r | movl r32,dr0-3 | 22 |
Move (register) to (debug register) | movl %ebx,%dr0 |
0F 23 /r | movl r32,dr6/dr7 | 16 |
Move (register) to (debug register) | movl %ebx,%dr6
movl %ebx,%dr7 |
0F 24 /r | movl tr6/tr7,r32 | 12 |
Move (test register) to (register) | movl %tr6,%ebx
movl %tr7,%ebx |
0F 26 /r | movl r32,tr6/tr7 | 12 |
Move (register) to (test register) | movl %ebx,%tr6
movl %ebx,%tr7 |
Operation
DEST := SRC;
Description
The above forms of MOV store or load the following special registers in or from a general purpose register:
- Control registers CR0, CR2, and CR3
- Debug Registers DR0, DR1, DR2, DR3, DR6, and DR7
- Test Registers TR6 and TR7
32-bit operands are always used with these instructions, regardless of the operand-size attribute.
Flags Affected
OF, SF, ZF, AF, PF, and CF are undefined
Protected Mode Exceptions
#GP(0) if the current privilege level is not 0
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
#GP(0) if instruction execution is attempted
Notes
The instructions must be executed at privilege level 0 or in
real-address mode; otherwise, a protection exception will be raised. The reg field within the ModRM byte specifies which of the
special registers in each category is involved. The two bits in the
field are always 11. The r/m field specifies the general register
involved.
MOVS/MOVSB/MOVSW/MOVSD -- Move Data from String to String
Opcode | Instruction | Clocks |
Description | Example |
A4 | movsb | 7 |
Move byte DS:[(E)SI] to ES:[(E)DI] | movsb |
A5 | movsw | 7 |
Move word DS:[(E)SI] to ES:[(E)DI] | movsw |
A5 | movsl | 7 |
Move dword DS:[(E)SI] to ES:[(E)DI] | movsl |
Operation
IF (instruction = MOVSD) OR (instruction has doubleword operands)
THEN OperandSize := 32;
ELSE OperandSize := 16;
IF AddressSize = 16
THEN use SI for source-index and DI for destination-index;
ELSE (* AddressSize = 32 *)
use ESI for source-index and EDI for destination-index;
FI;
IF byte type of instruction
THEN
[destination-index] := [source-index]; (* byte assignment *)
IF DF = 0 THEN IncDec := 1 ELSE IncDec := -1; FI;
ELSE
IF OperandSize = 16
THEN
[destination-index] := [source-index]; (* word assignment *)
IF DF = 0 THEN IncDec := 2 ELSE IncDec := -2; FI;
ELSE (* OperandSize = 32 *)
[destination-index] := [source-index]; (* doubleword assignment *)
IF DF = 0 THEN IncDec := 4 ELSE IncDec := -4; FI;
FI;
FI;
source-index := source-index + IncDec;
destination-index := destination-index + IncDec;
Description MOVS copies the byte or word at [(E)SI]
to the byte or word at ES:[(E)DI]. The destination operand must be
addressable from the ES register; no segment override is possible for
the destination. A segment override can be used for the source operand;
the default is DS. The addresses of the source and destination are determined
solely by the contents of (E)SI and (E)DI. Load the correct index
values into (E)SI and (E)DI before executing the MOVS instruction.
MOVSB, MOVSW, and MOVSD are synonyms for the byte, word, and doubleword
MOVS instructions. After the data is moved, both (E)SI and (E)DI are advanced automatically. If the direction flag is 0 (CLD was executed), the registers are incremented; if the direction flag is 1 (STD
was executed), the registers are decremented. The registers are
incremented or decremented by 1 if a byte was moved, 2 if a word was
moved, or 4 if a doubleword was moved. MOVS can be preceded by the REP prefix for block movement of CX bytes or words. Refer to the REP instruction for details of this operation.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
MOVSX -- Move with Sign-Extend
Opcode | Instruction | Clocks |
Description | Example |
0F BE /r | movsx r/m8,r16 | 3/6 |
Move byte to word with sign-extend | movsx %dl,%bx
movsx (%ebx,1),%bx
movsx m8(%ebx,1),%bx
movsx m8(%ebx,%ebp,1),%bx |
0F BE /r | movsx r/m8,r32 | 3/6 |
Move byte to dword, sign-extend | movsx %dl,%ebx
movsx (%ebx,1),%ebx
movsx m8(%ebx,1),%ebx
movsx m8(%ebx,%ebp,1),%ebx |
0F BF /r | movsx r/m16,r32 | 3/6 |
Move word to dword, sign-extend | movsx %cx,%ebx
movsx (%ebx,1),%ebx
movsx (%ebx,2),%ebx
movsx (%ebx,%ebp,1),%ebx |
Operation
DEST := SignExtend(SRC);
Description MOVSX reads the contents of the effective
address or register as a byte or a word, sign-extends the value to the
operand-size attribute of the instruction (16 or 32 bits), and stores
the result in the destination register. Flags Affected
None
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS or GS segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
MOVZX -- Move with Zero-Extend
Opcode | Instruction | Clocks |
Description | Example |
0F B6 /r | movzx r/m8,r16 | 3/6 |
Move byte to word with zero-extend | movzx %dl,%bx
movzx (%ebx,1),%bx
movzx m8(%ebx,1),%bx
movzx m8(%ebx,%ebp,1),%bx |
0F B6 /r | movzx r/m8,r32 | 3/6 |
Move byte to dword, zero-extend | movzx %dl,%ebx
movzx (%ebx,1),%ebx
movzx m8(%ebx,1),%ebx
movzx m8(%ebx,%ebp,1),%ebx |
0F B7 /r | movzx r/m16,r32 | 3/6 |
Move word to dword, zero-extend | movzx %cx,%ebx
movzx (%ebx,1),%ebx
movzx (%ebx,2),%ebx
movzx (%ebx,%ebp,1),%ebx |
Operation
DEST := ZeroExtend(SRC);
Description MOVZX reads the contents of the effective
address or register as a byte or a word, zero extends the value to the
operand-size attribute of the instruction (16 or 32 bits), and stores
the result in the destination register. Flags Affected
None
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS
segment; #PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
MUL -- Unsigned Multiplication of AL or AX
Opcode | Instruction | Clocks |
Description | Example |
F6 /4 | mulb r/m8,al | 9-14/12-17 |
Unsigned multiply (AX := AL * r/m byte) | mulb %dl
mulb (%ebx,1)
mulb m8(%ebx,1)
mulb m8(%ebx,%ebp,1) |
F7 /4 | mulw r/m16,ax | 9-22/12-25 |
Unsigned multiply (DX:AX := AX * r/m word) | mulw %cx
mulw (%ebx,1)
mulw (%ebx,2)
mulw (%ebx,%ebp,1) |
F7 /4 | mull r/m32,eax | 9-38/12-41 |
Unsigned multiply (EDX:EAX := EAX * r/m dword) | mull %ecx
mull (%ebx,2)
mull (%ebx,4)
mull (%ebx,%ebp,1) |
Notes The 80386 uses an early-out
multiply algorithm. The actual number of clocks depends on the position
of the most significant bit in the optimizing multiplier, shown
underlined above. The optimization occurs for positive and negative
multiplier values. Because of the early-out algorithm, clock counts
given are minimum to maximum. To calculate the actual clocks, use the
following formula:
Actual clock = if <> 0 then max(ceiling(log{2}(m)), 3) + 6 clocks;
Actual clock = if = 0 then 9 clocks
where m is the multiplier.
Operation
IF byte-size operation
THEN AX := AL * r/m8
ELSE (* word or doubleword operation *)
IF OperandSize = 16
THEN DX:AX := AX * r/m16
ELSE (* OperandSize = 32 *)
EDX:EAX := EAX * r/m32
FI;
FI;
Description
MUL performs unsigned multiplication. Its actions depend on the size of its operand, as follows:
- A
byte operand is multiplied by AL; the result is left in AX. The carry
and overflow flags are set to 0 if AH is 0; otherwise, they are set to
1.
- A word operand is multiplied by AX; the result is left in
DX:AX. DX contains the high-order 16 bits of the product. The carry and
overflow flags are set to 0 if DX is 0; otherwise, they are set to 1.
- A doubleword operand is multiplied by EAX and the result
is left in EDX:EAX. EDX contains the high-order 32 bits of the product.
The carry and overflow flags are set to 0 if EDX is 0; otherwise, they
are set to 1.
Flags Affected
OF and CF as described above; SF, ZF, AF, PF, and CF are undefined
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS
segment; #PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
NEG -- Two's Complement Negation
Opcode | Instruction | Clocks |
Description | Example |
F6 /3 | negb r/m8 | 2/6 |
Two's complement negate r/m byte | negb %dl
negb (%ebx,1)
negb m8(%ebx,1)
negb m8(%ebx,%ebp,1) |
F7 /3 | negw r/m16 | 2/6 |
Two's complement negate r/m word | negw %cx
negw (%ebx,1)
negw (%ebx,2)
negw (%ebx,%ebp,1) |
F7 /3 | negl r/m32 | 2/6 |
Two's complement negate r/m dword | negl %ecx
negl (%ebx,2)
negl (%ebx,4)
negl (%ebx,%ebp,1) |
Operation
IF r/m = 0 THEN CF := 0 ELSE CF := 1; FI;
r/m := - r/m;
Description NEG replaces the value of a register or
memory operand with its two's complement. The operand is subtracted
from zero, and the result is placed in the operand. The carry flag is set to 1, unless the operand is zero, in which case the carry flag is cleared to 0.
Flags Affected
CF as described above; OF, SF, ZF, and PF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page fault
NOP -- No Operation
Opcode | Instruction | Clocks |
Description | Example |
90 | nop | 3 |
No operation | nop |
Description NOP performs no operation. NOP
is a one-byte instruction that takes up space but affects none of the
machine context except (E)IP. NOP is an alias mnemonic for the XCHG (E)AX, (E)AX instruction.
Flags Affected
None
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
NOT -- One's Complement Negation
Opcode | Instruction | Clocks |
Description | Example |
F6 /2 | notb r/m8 | 2/6 |
Reverse each bit of r/m byte | notb %dl
notb (%ebx,1)
notb m8(%ebx,1)
notb m8(%ebx,%ebp,1) |
F7 /2 | notw r/m16 | 2/6 |
Reverse each bit of r/m word | notw %cx
notw (%ebx,1)
notw (%ebx,2)
notw (%ebx,%ebp,1) |
F7 /2 | notl r/m32 | 2/6 |
Reverse each bit of r/m dword | notl %ecx
notl (%ebx,2)
notl (%ebx,4)
notl (%ebx,%ebp,1) |
Operation
r/m := NOT r/m;
Description
NOT inverts the operand; every 1 becomes a 0, and vice versa.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page fault
OR -- Logical Inclusive OR
Opcode | Instruction | Clocks |
Description | Example |
0C ib | orb imm8,al | 2 |
OR immediate byte to AL | orb $0x7f,%al |
0D iw | orw imm16,ax | 2 |
OR immediate word to AX | orw $0x7fff,%ax |
0D id | orl imm32,eax | 2 |
OR immediate dword to EAX | orl $0x7fffffff,%eax |
80 /1 ib | orb imm8,r/m8 | 2/7 |
OR immediate byte to r/m byte | orb $0x7f,%dl
orb $0x7f,(%ebx,1)
orb $0x7f,m8(%ebx,1)
orb $0x7f,m8(%ebx,%ebp,1) |
81 /1 iw | orw imm16,r/m16 | 2/7 |
OR immediate word to r/m word | orw $0x7fff,%cx
orw $0x7fff,(%ebx,1)
orw $0x7fff,(%ebx,2)
orw $0x7fff,(%ebx,%ebp,1) |
81 /1 id | orl imm32,r/m32 | 2/7 |
OR immediate dword to r/m dword | orl $0x7fffffff,%ecx
orl $0x7fffffff,(%ebx,2)
orl $0x7fffffff,(%ebx,4)
orl $0x7fffffff,(%ebx,%ebp,1) |
83 /1 ib | orw imm8,r/m16 | 2/7 |
OR sign-extended immediate byte with r/m word | orw $0x7f,%cx
orw $0x7f,(%ebx,1)
orw $0x7f,(%ebx,2)
orw $0x7f,(%ebx,%ebp,1) |
83 /1 ib | orl imm8,r/m32 | 2/7 |
OR sign-extended immediate byte with r/m dword | orl $0x7f,%ecx
orl $0x7f,(%ebx,2)
orl $0x7f,(%ebx,4)
orl $0x7f,(%ebx,%ebp,1) |
08 /r | orb r8,r/m8 | 2/6 |
OR byte register to r/m byte | orb %bh,%dl
orb %bh,(%ebx,1)
orb %bh,m8(%ebx,1)
orb %bh,m8(%ebx,%ebp,1) |
09 /r | orw r16,r/m16 | 2/6 |
OR word register to r/m word | orw %bx,%cx
orw %bx,(%ebx,1)
orw %bx,(%ebx,2)
orw %bx,(%ebx,%ebp,1) |
09 /r | orl r32,r/m32 | 2/6 |
OR dword register to r/m dword | orl %ebx,%ecx
orl %ebx,(%ebx,2)
orl %ebx,(%ebx,4)
orl %ebx,(%ebx,%ebp,1) |
0A /r | orb r/m8,r8 | 2/7 |
OR byte register to r/m byte | orb %dl,%bh
orb (%ebx,1),%bh
orb m8(%ebx,1),%bh
orb m8(%ebx,%ebp,1),%bh |
0B /r | orw r/m16,r16 | 2/7 |
OR word register to r/m word | orw %cx,%bx
orw (%ebx,1),%bx
orw (%ebx,2),%bx
orw (%ebx,%ebp,1),%bx |
0B /r | orl r/m32,r32 | 2/7 |
OR dword register to r/m dword | orl %ecx,%ebx
orl (%ebx,2),%ebx
orl (%ebx,4),%ebx
orl (%ebx,%ebp,1),%ebx |
Operation
DEST := DEST OR SRC;
CF := 0;
OF := 0
Description OR computes the inclusive OR of its two
operands and places the result in the first operand. Each bit of the
result is 0 if both corresponding bits of the operands are 0;
otherwise, each bit is 1. Flags Affected
OF := 0, CF := 0; SF, ZF, and PF as described in Appendix C; AF is undefined
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page fault
OUT -- Output to Port
Opcode | Instruction | Clocks |
Description | Example |
E6 ib | outb al,imm8 | 10,pm=4*/24** |
Output byte AL to immediate port number | outb %al,$0x7f |
E7 ib | outw ax,imm8 | 10,pm=4*/24** |
Output word AL to immediate port number | outw %ax,$0x7f |
E7 ib | outl eax,imm8 | 10,pm=4*/24** |
Output dword AL to immediate port number | outl %eax,$0x7f |
EE | outb al,dx | 11,pm=5*/25** |
Output byte AL to port number in | outb %al,%dx |
EF | outw ax,dx | 11,pm=5*/25** |
Output word AL to port number in | outw %ax,%dx |
EF | outl eax,dx | 11,pm=5*/25** |
Output dword AL to port number in DX | outl %eax,%dx |
Notes
*If CPL <= IOPL
**If CPL > IOPL or if in virtual 8086 mode
Operation
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
IF NOT I-O-Permission (DEST, width(DEST))
THEN #GP(0);
FI;
FI;
[DEST] := SRC; (* I/O address space used *)
Description OUT transfers a data byte or data word
from the register (AL, AX, or EAX) given as the second operand to the
output port numbered by the first operand. Output to any port from 0 to
65535 is performed by placing the port number in the DX register and
then using an OUT instruction with DX as the first operand. If the
instruction contains an eight-bit port ID, that value is zero-extended
to 16 bits. Flags Affected
None
Protected Mode Exceptions
#GP(0) if the current privilege level is higher (has less privilege)
than IOPL and any of the corresponding I/O permission bits in TSS
equals 1 Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
#GP(0) fault if any of the corresponding I/O permission bits in TSS equals 1
OUTS/OUTSB/OUTSW/OUTSD -- Output String to Port
Opcode | Instruction | Clocks |
Description | Example |
6E | outsb | 14,pm=8*/28** |
Output byte DS:[(E)SI] to port in DX | outsb |
6F | outsw | 14,pm=8*/28** |
Output word DS:[(E)SI] to port in DX | outsw |
6F | outsl | 14,pm=8*/28** |
Output dword DS:[(E)SI] to port in DX | outsl |
Notes
*If CPL <= IOPL
**If CPL > IOPL or if in virtual 8086 mode
Operation
IF AddressSize = 16
THEN use SI for source-index;
ELSE (* AddressSize = 32 *)
use ESI for source-index;
FI;
IF (PE = 1) AND ((VM = 1) OR (CPL > IOPL))
THEN (* Virtual 8086 mode, or protected mode with CPL > IOPL *)
IF NOT I-O-Permission (DEST, width(DEST))
THEN #GP(0);
FI;
FI;
IF byte type of instruction
THEN
[DX] := [source-index]; (* Write byte at DX I/O address *)
IF DF = 0 THEN IncDec := 1 ELSE IncDec := -1; FI;
FI;
IF OperandSize = 16
THEN
[DX] := [source-index]; (* Write word at DX I/O address *)
IF DF = 0 THEN IncDec := 2 ELSE IncDec := -2; FI;
FI;
IF OperandSize = 32
THEN
[DX] := [source-index]; (* Write dword at DX I/O address *)
IF DF = 0 THEN IncDec := 4 ELSE IncDec := -4; FI;
FI;
FI;
source-index := source-index + IncDec;
Description OUTS transfers data from the memory byte,
word, or doubleword at the source-index register to the output port
addressed by the DX register. If the address-size attribute for this
instruction is 16 bits, SI is used for the source-index register;
otherwise, the address-size attribute is 32 bits, and ESI is used for
the source-index register. OUTS does not allow specification of the port number as an
immediate value. The port must be addressed through the DX register
value. Load the correct value into DX before executing the OUTS
instruction. The address of the source data is determined by the contents
of source-index register. Load the correct index value into SI or ESI
before executing the OUTS instruction. After the transfer, source-index register is advanced automatically. If the direction flag is 0 (CLD was executed), the source-index register is incremented; if the direction flag is 1 (STD
was executed), it is decremented. The amount of the increment or
decrement is 1 if a byte is output, 2 if a word is output, or 4 if a
doubleword is output. OUTSB, OUTSW, and OUTSD are synonyms for the byte, word, and doubleword OUTS instructions. OUTS can be preceded by the REP prefix for block output of CX bytes or words. Refer to the REP instruction for details on this operation.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if CPL is greater than IOPL and any of the corresponding I/O
permission bits in TSS equals 1; #GP(0) for an illegal memory operand
effective address in the CS, DS, or ES segments; #SS(0) for an illegal
address in the SS segment; #PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
#GP(0) fault if any of the corresponding I/O permission bits in TSS equals 1; #PF(fault-code) for a page fault
POP -- Pop a Word from the Stack
Opcode | Instruction | Clocks |
Description | Example |
8F /0 | popw m16 | 5 |
Pop top of stack into memory word | popw m16 |
8F /0 | popl m32 | 5 |
Pop top of stack into memory dword | popl m32 |
58 + rw | popw r16 | 4 |
Pop top of stack into word register | popw %bx |
58 + rd | popl r32 | 4 |
Pop top of stack into dword register | popl %ebx |
1F | popw ds | 7,pm=21 |
Pop top of stack into DS | popw %ds |
07 | popw es | 7,pm=21 |
Pop top of stack into ES | popw %es |
17 | popw ss | 7,pm=21 |
Pop top of stack into SS | popw %ss |
0F A1 | popw fs | 7,pm=21 |
Pop top of stack into FS | popw %fs |
0F A9 | popw gs | 7,pm=21 |
Pop top of stack into GS | popw %gs |
Operation
IF StackAddrSize = 16
THEN
IF OperandSize = 16
THEN
DEST := (SS:SP); (* copy a word *)
SP := SP + 2;
ELSE (* OperandSize = 32 *)
DEST := (SS:SP); (* copy a dword *)
SP := SP + 4;
FI;
ELSE (* StackAddrSize = 32 * )
IF OperandSize = 16
THEN
DEST := (SS:ESP); (* copy a word *)
ESP := ESP + 2;
ELSE (* OperandSize = 32 *)
DEST := (SS:ESP); (* copy a dword *)
ESP := ESP + 4;
FI;
FI;
Description POP replaces the previous contents of the
memory, the register, or the segment register operand with the word on
the top of the 80386 stack, addressed by SS:SP (address-size attribute
of 16 bits) or SS:ESP (addresssize attribute of 32 bits). The stack
pointer SP is incremented by 2 for an operand-size of 16 bits or by 4
for an operand-size of 32 bits. It then points to the new top of stack.
POP CS is not an 80386 instruction. Popping from the stack into the CS register is accomplished with a RET instruction.
If
the destination operand is a segment register (DS, ES, FS, GS, or SS),
the value popped must be a selector. In protected mode, loading the
selector initiates automatic loading of the descriptor information
associated with that selector into the hidden part of the segment
register; loading also initiates validation of both the selector and
the descriptor information. A null value (0000-0003) may be popped into the DS, ES, FS,
or GS register without causing a protection exception. An attempt to
reference a segment whose corresponding segment register is loaded with
a null value causes a #GP(0) exception. No memory reference occurs. The
saved value of the segment register is null. A POP SS instruction inhibits all interrupts, including NMI,
until after execution of the next instruction. This allows sequential
execution of POP SS and POP eSP instructions without danger of having
an invalid stack during an interrupt. However, use of the LSS instruction is the preferred method of loading the SS and eSP registers.
Loading a segment register while in protected mode results in special checks and actions, as described in the following listing:
IF SS is loaded:
IF selector is null THEN #GP(0);
Selector index must be within its descriptor table limits ELSE
#GP(selector);
Selector's RPL must equal CPL ELSE #GP(selector);
AR byte must indicate a writable data segment ELSE #GP(selector);
DPL in the AR byte must equal CPL ELSE #GP(selector);
Segment must be marked present ELSE #SS(selector);
Load SS register with selector;
Load SS register with descriptor;
IF DS, ES, FS or GS is loaded with non-null selector:
AR byte must indicate data or readable code segment ELSE
#GP(selector);
IF data or nonconforming code
THEN both the RPL and the CPL must be less than or equal to DPL in
AR byte
ELSE #GP(selector);
FI;
Segment must be marked present ELSE #NP(selector);
Load segment register with selector;
Load segment register with descriptor;
IF DS, ES, FS, or GS is loaded with a null selector:
Load segment register with selector
Clear valid bit in invisible portion of register
Flags Affected
None
Protected Mode Exceptions
#GP, #SS, and #NP if a segment register is being loaded; #SS(0) if the
current top of stack is not within the stack segment; #GP(0) if the
result is in a nonwritable segment; #GP(0) for an illegal memory
operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0)
for an illegal address in the SS segment; #PF(fault-code) for a page
fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page fault
POPA/POPAD -- Pop all General Registers
Opcode | Instruction | Clocks |
Description | Example |
61 | popa | 24 |
Pop DI, SI, BP, SP, BX, DX, CX, and AX | popa |
61 | popal | 24 |
Pop EDI, ESI, EBP, ESP, EDX, ECX, and EAX | popal |
Operation
IF OperandSize = 16 (* instruction = POPA *)
THEN
DI := Pop();
SI := Pop();
BP := Pop();
throwaway := Pop (); (* Skip SP *)
BX := Pop();
DX := Pop();
CX := Pop();
AX := Pop();
ELSE (* OperandSize = 32, instruction = POPAD *)
EDI := Pop();
ESI := Pop();
EBP := Pop();
throwaway := Pop (); (* Skip ESP *)
EBX := Pop();
EDX := Pop();
ECX := Pop();
EAX := Pop();
FI;
Description POPA pops the eight 16-bit general
registers. However, the SP value is discarded instead of loaded into
SP. POPA reverses a previous PUSHA, restoring the general registers to their values before PUSHA was executed. The first register popped is DI.
POPAD
pops the eight 32-bit general registers. The ESP value is discarded
instead of loaded into ESP. POPAD reverses the previous PUSHAD, restoring the general registers to their values before PUSHAD was executed. The first register popped is EDI.
Flags Affected
None
Protected Mode Exceptions
#SS(0) if the starting or ending stack address is not within the stack segment; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page fault
POPF/POPFD -- Pop Stack into FLAGS or EFLAGS Register
Opcode | Instruction | Clocks |
Description | Example |
9D | popf | 5 |
Pop top of stack FLAGS | popf |
9D | popfl | 5 |
Pop top of stack into EFLAGS | popfl |
Operation
Flags := Pop();
Description
POPF/POPFD pops the word or doubleword on the top of the stack and
stores the value in the flags register. If the operand-size attribute
of the instruction is 16 bits, then a word is popped and the value is
stored in FLAGS. If the operand-size attribute is 32 bits, then a
doubleword is popped and the value is stored in EFLAGS. Refer to Chapter 2 and Chapter 4
for information about the FLAGS and EFLAGS registers. Note that bits 16
and 17 of EFLAGS, called VM and RF, respectively, are not affected by
POPF or POPFD. The I/O privilege level is altered only when executing at
privilege level 0. The interrupt flag is altered only when executing at
a level at least as privileged as the I/O privilege level.
(Real-address mode is equivalent to privilege level 0.) If a POPF
instruction is executed with insufficient privilege, an exception does
not occur, but the privileged bits do not change. Flags Affected
All flags except VM and RF
Protected Mode Exceptions
#SS(0) if the top of stack is not within the stack segment
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
#GP(0) fault if IOPL is less than 3, to permit emulation
PUSH -- Push Operand onto the Stack
Opcode | Instruction | Clocks |
Description | Example |
FF /6 | pushw m16 | 5 |
Push memory word | pushw m16 |
FF /6 | pushl m32 | 5 |
Push memory dword | pushl m32 |
50 + /r | pushw r16 | 2 |
Push register word | pushw %bx |
50 + /r | pushl r32 | 2 |
Push register dword | pushl %ebx |
68 | pushw imm16 | 2 |
Push immediate word | pushw $0x7fff |
68 | pushl imm32 | 2 |
Push immediate dword | pushl $0x7fffffff |
0E | pushw cs | 2 |
Push CS | pushw %cs |
16 | pushw ss | 2 |
Push SS | pushw %ss |
1E | pushw ds | 2 |
Push DS | pushw %ds |
06 | pushw es | 2 |
Push ES | pushw %es |
0F A0 | pushw fs | 2 |
Push FS | pushw %fs |
OF A8 | pushw gs | 2 |
Push GS | pushw %gs |
Operation
IF StackAddrSize = 16
THEN
IF OperandSize = 16 THEN
SP := SP - 2;
(SS:SP) := (SOURCE); (* word assignment *)
ELSE
SP := SP - 4;
(SS:SP) := (SOURCE); (* dword assignment *)
FI;
ELSE (* StackAddrSize = 32 *)
IF OperandSize = 16
THEN
ESP := ESP - 2;
(SS:ESP) := (SOURCE); (* word assignment *)
ELSE
ESP := ESP - 4;
(SS:ESP) := (SOURCE); (* dword assignment *)
FI;
FI;
Description PUSH decrements the stack pointer by 2 if
the operand-size attribute of the instruction is 16 bits; otherwise, it
decrements the stack pointer by 4. PUSH then places the operand on the
new top of stack, which is pointed to by the stack pointer. The 80386 PUSH eSP instruction pushes the value of eSP as it
existed before the instruction. This differs from the 8086, where PUSH
SP pushes the new value (decremented by 2). Flags Affected
None
Protected Mode Exceptions
#SS(0) if the new value of SP or ESP is outside the stack segment
limit; #GP(0) for an illegal memory operand effective address in the
CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS
segment; #PF(fault-code) for a page fault Real Address Mode Exceptions
None; if SP or ESP is 1, the 80386 shuts down due to a lack of stack space
Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page fault
PUSHA/PUSHAD -- Push all General Registers
Opcode | Instruction | Clocks |
Description | Example |
60 | pusha | 18 |
Push AX, CX, DX, BX, original SP, BP, SI, and DI | pusha |
60 | pushal | 18 |
Push EAX, ECX, EDX, EBX, original ESP, EBP, ESI, and EDI | pushal |
Operation
IF OperandSize = 16 (* PUSHA instruction *)
THEN
Temp := (SP);
Push(AX);
Push(CX);
Push(DX);
Push(BX);
Push(Temp);
Push(BP);
Push(SI);
Push(DI);
ELSE (* OperandSize = 32, PUSHAD instruction *)
Temp := (ESP);
Push(EAX);
Push(ECX);
Push(EDX);
Push(EBX);
Push(Temp);
Push(EBP);
Push(ESI);
Push(EDI);
FI;
Description PUSHA and PUSHAD save the 16-bit or
32-bit general registers, respectively, on the 80386 stack. PUSHA
decrements the stack pointer (SP) by 16 to hold the eight word values.
PUSHAD decrements the stack pointer (ESP) by 32 to hold the eight
doubleword values. Because the registers are pushed onto the stack in
the order in which they were given, they appear in the 16 or 32 new
stack bytes in reverse order. The last register pushed is DI or EDI. Flags Affected
None
Protected Mode Exceptions
#SS(0) if the starting or ending stack address is outside the stack segment limit; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Before executing PUSHA or PUSHAD, the 80386 shuts down if SP or ESP
equals 1, 3, or 5; if SP or ESP equals 7, 9, 11, 13, or 15, exception
13 occurs Virtual 8086 Mode Exceptions
Same exceptions as in real-address mode; #PF(fault-code) for a page fault
PUSHF/PUSHFD -- Push Flags Register onto the Stack
Opcode | Instruction | Clocks |
Description | Example |
9C | pushf | 4 |
Push FLAGS | pushf |
9C | pushfl | 4 |
Push EFLAGS | pushfl |
Operation
IF OperandSize = 32
THEN push(EFLAGS);
ELSE push(FLAGS);
FI;
Description PUSHF decrements the stack pointer by 2
and copies the FLAGS register to the new top of stack; PUSHFD
decrements the stack pointer by 4, and the 80386 EFLAGS register is
copied to the new top of stack which is pointed to by SS:eSP. Refer to Chapter 2 and Chapter 4 for information on the EFLAGS register.
Flags Affected
None
Protected Mode Exceptions
#SS(0) if the new value of eSP is outside the stack segment boundaries
Real Address Mode Exceptions
None; the 80386 shuts down due to a lack of stack space
Virtual 8086 Mode Exceptions
#GP(0) fault if IOPL is less than 3, to permit emulation
RCL/RCR/ROL/ROR -- Rotate
Opcode | Instruction | Clocks |
Description | Example |
D0 /2 | rclb 1,r/m8 | 9/10 |
Rotate 9 bits (CF,r/m byte) left once | rclb $1,%dl
rclb $1,(%ebx,1)
rclb $1,m8(%ebx,1)
rclb $1,m8(%ebx,%ebp,1) |
D2 /2 | rclb cl,r/m8 | 9/10 |
Rotate 9 bits (CF,r/m byte) left CL times | rclb %cl,%dl
rclb %cl,(%ebx,1)
rclb %cl,m8(%ebx,1)
rclb %cl,m8(%ebx,%ebp,1) |
C0 /2 ib | rclb imm8,r/m8 | 9/10 |
Rotate 9 bits (CF,r/m byte) left imm8 times | rclb $0x7f,%dl
rclb $0x7f,(%ebx,1)
rclb $0x7f,m8(%ebx,1)
rclb $0x7f,m8(%ebx,%ebp,1) |
D1 /2 | rclw 1,r/m16 | 9/10 |
Rotate 17 bits (CF,r/m word) left once | rclw $1,%cx
rclw $1,(%ebx,1)
rclw $1,(%ebx,2)
rclw $1,(%ebx,%ebp,1) |
D3 /2 | rclw cl,r/m16 | 9/10 |
Rotate 17 bits (CF,r/m word) left CL times | rclw %cl,%cx
rclw %cl,(%ebx,1)
rclw %cl,(%ebx,2)
rclw %cl,(%ebx,%ebp,1) |
C1 /2 ib | rclw imm8,r/m16 | 9/10 |
Rotate 17 bits (CF,r/m word) left imm8 times | rclw $0x7f,%cx
rclw $0x7f,(%ebx,1)
rclw $0x7f,(%ebx,2)
rclw $0x7f,(%ebx,%ebp,1) |
D1 /2 | rcll 1,r/m32 | 9/10 |
Rotate 33 bits (CF,r/m dword) left once | rcll $1,%ecx
rcll $1,(%ebx,2)
rcll $1,(%ebx,4)
rcll $1,(%ebx,%ebp,1) |
D3 /2 | rcll cl,r/m32 | 9/10 |
Rotate 33 bits (CF,r/m dword) left CL times | rcll %cl,%ecx
rcll %cl,(%ebx,2)
rcll %cl,(%ebx,4)
rcll %cl,(%ebx,%ebp,1) |
C1 /2 ib | rcll imm8,r/m32 | 9/10 |
Rotate 33 bits (CF,r/m dword) left imm8 times | rcll $0x7f,%ecx
rcll $0x7f,(%ebx,2)
rcll $0x7f,(%ebx,4)
rcll $0x7f,(%ebx,%ebp,1) |
D0 /3 | rcrb 1,r/m8 | 9/10 |
Rotate 9 bits (CF,r/m byte) right once | rcrb $1,%dl
rcrb $1,(%ebx,1)
rcrb $1,m8(%ebx,1)
rcrb $1,m8(%ebx,%ebp,1) |
D2 /3 | rcrb cl,r/m8 | 9/10 |
Rotate 9 bits (CF,r/m byte) right CL times | rcrb %cl,%dl
rcrb %cl,(%ebx,1)
rcrb %cl,m8(%ebx,1)
rcrb %cl,m8(%ebx,%ebp,1) |
C0 /3 ib | rcrb imm8,r/m8 | 9/10 |
Rotate 9 bits (CF,r/m byte) right imm8 times | rcrb $0x7f,%dl
rcrb $0x7f,(%ebx,1)
rcrb $0x7f,m8(%ebx,1)
rcrb $0x7f,m8(%ebx,%ebp,1) |
D1 /3 | rcrw 1,r/m16 | 9/10 |
Rotate 17 bits (CF,r/m word) right once | rcrw $1,%cx
rcrw $1,(%ebx,1)
rcrw $1,(%ebx,2)
rcrw $1,(%ebx,%ebp,1) |
D3 /3 | rcrw cl,r/m16 | 9/10 |
Rotate 17 bits (CF,r/m word) right CL times | rcrw %cl,%cx
rcrw %cl,(%ebx,1)
rcrw %cl,(%ebx,2)
rcrw %cl,(%ebx,%ebp,1) |
C1 /3 ib | rcrw imm8,r/m16 | 9/10 |
Rotate 17 bits (CF,r/m word) right imm8 times | rcrw $0x7f,%cx
rcrw $0x7f,(%ebx,1)
rcrw $0x7f,(%ebx,2)
rcrw $0x7f,(%ebx,%ebp,1) |
D1 /3 | rcrl 1,r/m32 | 9/10 |
Rotate 33 bits (CF,r/m dword) right once | rcrl $1,%ecx
rcrl $1,(%ebx,2)
rcrl $1,(%ebx,4)
rcrl $1,(%ebx,%ebp,1) |
D3 /3 | rcrl cl,r/m32 | 9/10 |
Rotate 33 bits (CF,r/m dword) right CL times | rcrl %cl,%ecx
rcrl %cl,(%ebx,2)
rcrl %cl,(%ebx,4)
rcrl %cl,(%ebx,%ebp,1) |
C1 /3 ib | rcrl imm8,r/m32 | 9/10 |
Rotate 33 bits (CF,r/m dword) right imm8 times | rcrl $0x7f,%ecx
rcrl $0x7f,(%ebx,2)
rcrl $0x7f,(%ebx,4)
rcrl $0x7f,(%ebx,%ebp,1) |
D0 /0 | rolb 1,r/m8 | 3/7 |
Rotate 8 bits r/m byte left once | rolb $1,%dl
rolb $1,(%ebx,1)
rolb $1,m8(%ebx,1)
rolb $1,m8(%ebx,%ebp,1) |
D2 /0 | rolb cl,r/m8 | 3/7 |
Rotate 8 bits r/m byte left CL times | rolb %cl,%dl
rolb %cl,(%ebx,1)
rolb %cl,m8(%ebx,1)
rolb %cl,m8(%ebx,%ebp,1) |
C0 /0 ib | rolb imm8,r/m8 | 3/7 |
Rotate 8 bits r/m byte left imm8 times | rolb $0x7f,%dl
rolb $0x7f,(%ebx,1)
rolb $0x7f,m8(%ebx,1)
rolb $0x7f,m8(%ebx,%ebp,1) |
D1 /0 | rolw 1,r/m16 | 3/7 |
Rotate 16 bits r/m word left once | rolw $1,%cx
rolw $1,(%ebx,1)
rolw $1,(%ebx,2)
rolw $1,(%ebx,%ebp,1) |
D3 /0 | rolw cl,r/m16 | 3/7 |
Rotate 16 bits r/m word left CL times | rolw %cl,%cx
rolw %cl,(%ebx,1)
rolw %cl,(%ebx,2)
rolw %cl,(%ebx,%ebp,1) |
C1 /0 ib | rolw imm8,r/m16 | 3/7 |
Rotate 16 bits r/m word left imm8 times | rolw $0x7f,%cx
rolw $0x7f,(%ebx,1)
rolw $0x7f,(%ebx,2)
rolw $0x7f,(%ebx,%ebp,1) |
D1 /0 | roll 1,r/m32 | 3/7 |
Rotate 32 bits r/m dword left once | roll $1,%ecx
roll $1,(%ebx,2)
roll $1,(%ebx,4)
roll $1,(%ebx,%ebp,1) |
D3 /0 | roll cl,r/m32 | 3/7 |
Rotate 32 bits r/m dword left CL times | roll %cl,%ecx
roll %cl,(%ebx,2)
roll %cl,(%ebx,4)
roll %cl,(%ebx,%ebp,1) |
C1 /0 ib | roll imm8,r/m32 | 3/7 |
Rotate 32 bits r/m dword left imm8 times | roll $0x7f,%ecx
roll $0x7f,(%ebx,2)
roll $0x7f,(%ebx,4)
roll $0x7f,(%ebx,%ebp,1) |
D0 /1 | rorb 1,r/m8 | 3/7 |
Rotate 8 bits r/m byte right once | rorb $1,%dl
rorb $1,(%ebx,1)
rorb $1,m8(%ebx,1)
rorb $1,m8(%ebx,%ebp,1) |
D2 /1 | rorb cl,r/m8 | 3/7 |
Rotate 8 bits r/m byte right CL times | rorb %cl,%dl
rorb %cl,(%ebx,1)
rorb %cl,m8(%ebx,1)
rorb %cl,m8(%ebx,%ebp,1) |
C0 /1 ib | rorb imm8,r/m8 | 3/7 |
Rotate 8 bits r/m word right imm8 times | rorb $0x7f,%dl
rorb $0x7f,(%ebx,1)
rorb $0x7f,m8(%ebx,1)
rorb $0x7f,m8(%ebx,%ebp,1) |
D1 /1 | rorw 1,r/m16 | 3/7 |
Rotate 16 bits r/m word right once | rorw $1,%cx
rorw $1,(%ebx,1)
rorw $1,(%ebx,2)
rorw $1,(%ebx,%ebp,1) |
D3 /1 | rorw cl,r/m16 | 3/7 |
Rotate 16 bits r/m word right CL times | rorw %cl,%cx
rorw %cl,(%ebx,1)
rorw %cl,(%ebx,2)
rorw %cl,(%ebx,%ebp,1) |
C1 /1 ib | rorw imm8,r/m16 | 3/7 |
Rotate 16 bits r/m word right imm8 times | rorw $0x7f,%cx
rorw $0x7f,(%ebx,1)
rorw $0x7f,(%ebx,2)
rorw $0x7f,(%ebx,%ebp,1) |
D1 /1 | rorl 1,r/m32 | 3/7 |
Rotate 32 bits r/m dword right once | rorl $1,%ecx
rorl $1,(%ebx,2)
rorl $1,(%ebx,4)
rorl $1,(%ebx,%ebp,1) |
D3 /1 | rorl cl,r/m32 | 3/7 |
Rotate 32 bits r/m dword right CL times | rorl %cl,%ecx
rorl %cl,(%ebx,2)
rorl %cl,(%ebx,4)
rorl %cl,(%ebx,%ebp,1) |
C1 /1 ib | rorl imm8,r/m32 | 3/7 |
Rotate 32 bits r/m dword right imm8 times | rorl $0x7f,%ecx
rorl $0x7f,(%ebx,2)
rorl $0x7f,(%ebx,4)
rorl $0x7f,(%ebx,%ebp,1) |
Operation
(* ROL - Rotate Left *)
temp := COUNT;
WHILE (temp <> 0)
DO
tmpcf := high-order bit of (r/m);
r/m := r/m * 2 + (tmpcf);
temp := temp - 1;
OD;
IF COUNT = 1
THEN
IF high-order bit of r/m <> CF
THEN OF := 1;
ELSE OF := 0;
FI;
ELSE OF := undefined;
FI;
(* ROR - Rotate Right *)
temp := COUNT;
WHILE (temp <> 0 )
DO
tmpcf := low-order bit of (r/m);
r/m := r/m / 2 + (tmpcf * 2^(width(r/m)));
temp := temp - 1;
DO;
IF COUNT = 1
THEN
IF (high-order bit of r/m) <> (bit next to high-order bit of r/m)
THEN OF := 1;
ELSE OF := 0;
FI;
ELSE OF := undefined;
FI;
Description Each rotate instruction shifts the bits
of the register or memory operand given. The left rotate instructions
shift all the bits upward, except for the top bit, which is returned to
the bottom. The right rotate instructions do the reverse: the bits
shift downward until the bottom bit arrives at the top. For the RCL and RCR instructions, the carry flag is part of the
rotated quantity. RCL shifts the carry flag into the bottom bit and
shifts the top bit into the carry flag; RCR shifts the carry flag into
the top bit and shifts the bottom bit into the carry flag. For the ROL
and ROR instructions, the original value of the carry flag is not a
part of the result, but the carry flag receives a copy of the bit that
was shifted from one end to the other. The rotate is repeated the number of times indicated by the
second operand, which is either an immediate number or the contents of
the CL register. To reduce the maximum instruction execution time, the
80386 does not allow rotation counts greater than 31. If a rotation
count greater than 31 is attempted, only the bottom five bits of the
rotation are used. The 8086 does not mask rotation counts. The 80386 in
Virtual 8086 Mode does mask rotation counts. The overflow flag is defined only for the single-rotate
forms of the instructions (second operand := 1). It is undefined in all
other cases. For left shifts/rotates, the CF bit after the shift is
XORed with the high-order result bit. For right shifts/rotates, the
high-order two bits of the result are XORed to get OF. Flags Affected
OF only for single rotates; OF is undefined for multi-bit rotates; CF as described above
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
REP/REPE/REPZ/REPNE/REPNZ -- Repeat Following String Operation
Opcode | Instruction | Clocks |
Description | Example |
F3 6C | rep insb | 13+6*(E)CX, |
Input (E)CX bytes from port DX into ES:[(E)DI] | rep insb |
F3 6D | rep insw | 13+6*(E)CX, |
Input (E)CX words from port DX into ES:[(E)DI] | rep insw |
F3 6D | rep insl | 13+6*(E)CX, |
Input (E)CX dwords from port DX into ES:[(E)DI] | rep insl |
F3 A4 | rep movsb | 5+4*(E)CX |
Move (E)CX bytes from [(E)SI] to ES:[(E)DI] | rep movsb |
F3 A5 | rep movsw | 5+4*(E)CX |
Move (E)CX words from [(E)SI] to ES:[(E)DI] | rep movsw |
F3 A5 | rep movsl | 5+4*(E)CX |
Move (E)CX dwords from [(E)SI] to ES:[(E)DI] | rep movsl |
F3 AA | rep stosb | 5+5*(E)CX |
Fill (E)CX bytes at ES:[(E)DI] with AL | rep stosb |
F3 AB | rep stosw | 5+5*(E)CX |
Fill (E)CX words at ES:[(E)DI] with AX | rep stosw |
F3 AB | rep stosl | 5+5*(E)CX |
Fill (E)CX dwords at ES:[(E)DI] with EAX | rep stosl |
F3 A6 | repe cmpsb | 5+9*N |
Find nonmatching bytes in ES:[(E)DI] and [(E)SI] | repe cmpsb |
F3 A7 | repe cmpsw | 5+9*N |
Find nonmatching words in ES:[(E)DI] and [(E)SI] | repe cmpsw |
F3 A7 | repe cmpsl | 5+9*N |
Find nonmatching dwords in ES:[(E)DI] and [(E)SI] | repe cmpsl |
F3 AE | repe scasb | 5+8*N |
Find non-AL byte starting at ES:[(E)DI] | repe scasb |
F3 AF | repe scasw | 5+8*N |
Find non-AX word starting at ES:[(E)DI] | repe scasw |
F3 AF | repe scasl | 5+8*N |
Find non-EAX dword starting at ES:[(E)DI] | repe scasl |
F2 A6 | repne cmpsb | 5+9*N |
Find matching bytes in ES:[(E)DI] and [(E)SI] | repne cmpsb |
F2 A7 | repne cmpsw | 5+9*N |
Find matching words in ES:[(E)DI] and [(E)SI] | repne cmpsw |
F2 A7 | repne cmpsl | 5+9*N |
Find matching dwords in ES:[(E)DI] and [(E)SI] | repne cmpsl |
F2 AE | repne scasb | 5+8*N |
Find AL, starting at ES:[(E)DI] | repne scasb |
F2 AF | repne scasw | 5+8*N |
Find AX, starting at ES:[(E)DI] | repne scasw |
F2 AF | repne scasl | 5+8*N |
Find EAX, starting at ES:[(E)DI] | repne scasl |
Operation
IF AddressSize = 16
THEN use CX for CountReg;
ELSE (* AddressSize = 32 *) use ECX for CountReg;
FI;
WHILE CountReg <> 0
DO
service pending interrupts (if any);
perform primitive string instruction;
CountReg := CountReg - 1;
IF primitive operation is CMPB, CMPW, SCAB, or SCAW
THEN
IF (instruction is REP/REPE/REPZ) AND (ZF=1)
THEN exit WHILE loop
ELSE
IF (instruction is REPNZ or REPNE) AND (ZF=0)
THEN exit WHILE loop;
FI;
FI;
FI;
OD;
Description REP, REPE (repeat while equal), and REPNE
(repeat while not equal) are prefix that are applied to string
operation. Each prefix cause the string instruction that follows to be
repeated the number of times indicated in the count register or (for
REPE and REPNE) until the indicated condition in the zero flag is no
longer met. Synonymous forms of REPE and REPNE are REPZ and REPNZ, respectively.
The REP prefixes apply only to one string instruction at a time. To repeat a block of instructions, use the LOOP instruction or another looping construct.
The precise action for each iteration is as follows:
- If
the address-size attribute is 16 bits, use CX for the count register;
if the address-size attribute is 32 bits, use ECX for the count
register.
- Check CX. If it is zero, exit the iteration, and move to the next instruction.
- Acknowledge any pending interrupts.
- Perform the string operation once.
- Decrement CX or ECX by one; no flags are modified.
- Check the zero flag if the string operation is SCAS or CMPS.
If the repeat condition does not hold, exit the iteration and move to
the next instruction. Exit the iteration if the prefix is REPE and ZF
is 0 (the last comparison was not equal), or if the prefix is REPNE and
ZF is one (the last comparison was equal).
- Return to step 1 for the next iteration.
Repeated CMPS and SCAS
instructions can be exited if the count is exhausted or if the zero
flag fails the repeat condition. These two cases can be distinguished
by using either the JCXZ instruction, or by using the conditional jumps that test the zero flag (JZ, JNZ, and JNE).
Flags Affected
ZF by REP CMPS and REP SCAS as described above
Protected Mode Exceptions
#UD if a repeat prefix is used before an instruction that is not in the
list above; further exceptions can be generated when the string
operation is executed; refer to the descriptions of the string
instructions themselves Real Address Mode Exceptions Interrupt 6 if a repeat
prefix is used before an instruction that is not in the list above;
further exceptions can be generated when the string operation is
executed; refer to the descriptions of the string instructions
themselves Virtual 8086 Mode Exceptions #UD if a repeat prefix is
used before an instruction that is not in the list above; further
exceptions can be generated when the string operation is executed;
refer to the descriptions of the string instructions themselves Notes
Not all input/output ports can handle the rate at which the REP INS and REP OUTS instructions execute.
RET -- Return from Procedure
Opcode | Instruction | Clocks |
Description | Example |
C3 | ret | 10+m |
Return (near) to caller | ret |
CB | ret | 18+m,pm=32+m |
Return (far) to caller, same privilege | ret |
CB | ret | pm=68 |
Return (far), lesser privilege, switch stacks | ret |
C2 iw | retw imm16 | 10+m |
Return (near), pop imm16 bytes of parameters | retw $0x7fff |
CA iw | retw imm16 | 18+m,pm=32+m |
Return (far), same privilege, pop imm16 bytes | retw $0x7fff |
CA iw | retw imm16 | pm=68 |
Return (far), lesser privilege, pop imm16 bytes | retw $0x7fff |
Operation
IF instruction = near RET
THEN;
IF OperandSize = 16
THEN
IP := Pop();
EIP := EIP AND 0000FFFFH;
ELSE (* OperandSize = 32 *)
EIP := Pop();
FI;
IF instruction has immediate operand THEN eSP := eSP + imm16; FI;
FI;
IF (PE = 0 OR (PE = 1 AND VM = 1))
(* real mode or virtual 8086 mode *)
AND instruction = far RET
THEN;
IF OperandSize = 16
THEN
IP := Pop();
EIP := EIP AND 0000FFFFH;
CS := Pop(); (* 16-bit pop *)
ELSE (* OperandSize = 32 *)
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16-bits discarded *)
FI;
IF instruction has immediate operand THEN eSP := eSP + imm16; FI;
FI;
IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)
AND instruction = far RET
THEN
IF OperandSize=32
THEN Third word on stack must be within stack limits else #SS(0);
ELSE Second word on stack must be within stack limits else #SS(0);
FI;
Return selector RPL must be >= CPL ELSE #GP(return selector)
IF return selector RPL = CPL
THEN GOTO SAME-LEVEL;
ELSE GOTO OUTER-PRIVILEGE-LEVEL;
FI;
FI;
SAME-LEVEL:
Return selector must be non-null ELSE #GP(0)
Selector index must be within its descriptor table limits ELSE
#GP(selector)
Descriptor AR byte must indicate code segment ELSE #GP(selector)
IF non-conforming
THEN code segment DPL must equal CPL;
ELSE #GP(selector);
FI;
IF conforming
THEN code segment DPL must be <= CPL;
ELSE #GP(selector);
FI;
Code segment must be present ELSE #NP(selector);
Top word on stack must be within stack limits ELSE #SS(0);
IP must be in code segment limit ELSE #GP(0);
IF OperandSize=32
THEN
Load CS:EIP from stack
Load CS register with descriptor
Increment eSP by 8 plus the immediate offset if it exists
ELSE (* OperandSize=16 *)
Load CS:IP from stack
Load CS register with descriptor
Increment eSP by 4 plus the immediate offset if it exists
FI;
OUTER-PRIVILEGE-LEVEL:
IF OperandSize=32
THEN Top (16+immediate) bytes on stack must be within stack limits
ELSE #SS(0);
ELSE Top (8+immediate) bytes on stack must be within stack limits ELSE
#SS(0);
FI;
Examine return CS selector and associated descriptor:
Selector must be non-null ELSE #GP(0);
Selector index must be within its descriptor table limits ELSE
#GP(selector)
Descriptor AR byte must indicate code segment ELSE #GP(selector);
IF non-conforming
THEN code segment DPL must equal return selector RPL
ELSE #GP(selector);
FI;
IF conforming
THEN code segment DPL must be <= return selector RPL;
ELSE #GP(selector);
FI;
Segment must be present ELSE #NP(selector)
Examine return SS selector and associated descriptor:
Selector must be non-null ELSE #GP(0);
Selector index must be within its descriptor table limits
ELSE #GP(selector);
Selector RPL must equal the RPL of the return CS selector ELSE
#GP(selector);
Descriptor AR byte must indicate a writable data segment ELSE
#GP(selector);
Descriptor DPL must equal the RPL of the return CS selector ELSE
#GP(selector);
Segment must be present ELSE #NP(selector);
IP must be in code segment limit ELSE #GP(0);
Set CPL to the RPL of the return CS selector;
IF OperandMode=32
THEN
Load CS:EIP from stack;
Set CS RPL to CPL;
Increment eSP by 8 plus the immediate offset if it exists;
Load SS:eSP from stack;
ELSE (* OperandMode=16 *)
Load CS:IP from stack;
Set CS RPL to CPL;
Increment eSP by 4 plus the immediate offset if it exists;
Load SS:eSP from stack;
FI;
Load the CS register with the return CS descriptor;
Load the SS register with the return SS descriptor;
For each of ES, FS, GS, and DS
DO
IF the current register setting is not valid for the outer level,
set the register to null (selector := AR := 0);
To be valid, the register setting must satisfy the following
properties:
Selector index must be within descriptor table limits;
Descriptor AR byte must indicate data or readable code segment;
IF segment is data or non-conforming code, THEN
DPL must be >= CPL, or DPL must be >= RPL;
FI;
OD;
Description
RET transfers control to a return address located on the stack. The address is usually placed on the stack by a CALL instruction, and the return is made to the instruction that follows the CALL.
The
optional numeric parameter to RET gives the number of stack bytes
(OperandMode=16) or words (OperandMode=32) to be released after the
return address is popped. These items are typically used as input
parameters to the procedure called. For the intrasegment (near) return, the address on the stack
is a segment offset, which is popped into the instruction pointer. The
CS register is unchanged. For the intersegment (far) return, the
address on the stack is a long pointer. The offset is popped first,
followed by the selector. In real mode, CS and IP are loaded directly. In Protected
Mode, an intersegment return causes the processor to check the
descriptor addressed by the return selector. The AR byte of the
descriptor must indicate a code segment of equal or lesser privilege
(or greater or equal numeric value) than the current privilege level.
Returns to a lesser privilege level cause the stack to be reloaded from
the value saved beyond the parameter block. The DS, ES, FS, and GS segment registers can be set to 0 by
the RET instruction during an interlevel transfer. If these registers
refer to segments that cannot be used by the new privilege level, they
are set to 0 to prevent unauthorized access from the new privilege
level. Flags Affected
None
Protected Mode Exceptions
#GP, #NP, or #SS, as described under "
Operation
" above; #PF(fault-code) for a page fault
Real Address Mode Exceptions
Interrupt 13 if any part of the operand would be outside the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
SAHF -- Store AH into Flags
Opcode | Instruction | Clocks |
Description | Example |
9E | sahf | 3 |
Store AH into flags SF ZF xx AF xx PF xx CF | sahf |
Operation
SF:ZF:xx:AF:xx:PF:xx:CF := AH;
Description
SAHF loads the flags listed above with values from the AH register, from bits 7, 6, 4, 2, and 0, respectively.
Flags Affected
SF, ZF, AF, PF, and CF as described above
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
SAL/SAR/SHL/SHR -- Shift Instructions
Opcode | Instruction | Clocks |
Description | Example |
D0 /4 | salb 1,r/m8 | 3/7 |
Multiply r/m byte by 2, once | salb $1,%dl
salb $1,(%ebx,1)
salb $1,m8(%ebx,1)
salb $1,m8(%ebx,%ebp,1) |
D2 /4 | salb cl,r/m8 | 3/7 |
Multiply r/m byte by 2, CL times | salb %cl,%dl
salb %cl,(%ebx,1)
salb %cl,m8(%ebx,1)
salb %cl,m8(%ebx,%ebp,1) |
C0 /4 ib | salb imm8,r/m8 | 3/7 |
Multiply r/m byte by 2, imm8 times | salb $0x7f,%dl
salb $0x7f,(%ebx,1)
salb $0x7f,m8(%ebx,1)
salb $0x7f,m8(%ebx,%ebp,1) |
D1 /4 | salw 1,r/m16 | 3/7 |
Multiply r/m word by 2, once | salw $1,%cx
salw $1,(%ebx,1)
salw $1,(%ebx,2)
salw $1,(%ebx,%ebp,1) |
D3 /4 | salw cl,r/m16 | 3/7 |
Multiply r/m word by 2, CL times | salw %cl,%cx
salw %cl,(%ebx,1)
salw %cl,(%ebx,2)
salw %cl,(%ebx,%ebp,1) |
C1 /4 ib | salw imm8,r/m16 | 3/7 |
Multiply r/m word by 2, imm8 times | salw $0x7f,%cx
salw $0x7f,(%ebx,1)
salw $0x7f,(%ebx,2)
salw $0x7f,(%ebx,%ebp,1) |
D1 /4 | sall 1,r/m32 | 3/7 |
Multiply r/m dword by 2, once | sall $1,%ecx
sall $1,(%ebx,2)
sall $1,(%ebx,4)
sall $1,(%ebx,%ebp,1) |
D3 /4 | sall cl,r/m32 | 3/7 |
Multiply r/m dword by 2, CL times | sall %cl,%ecx
sall %cl,(%ebx,2)
sall %cl,(%ebx,4)
sall %cl,(%ebx,%ebp,1) |
C1 /4 ib | sall imm8,r/m32 | 3/7 |
Multiply r/m dword by 2, imm8 times | sall $0x7f,%ecx
sall $0x7f,(%ebx,2)
sall $0x7f,(%ebx,4)
sall $0x7f,(%ebx,%ebp,1) |
D0 /7 | sarb 1,r/m8 | 3/7 |
Signed divide^(1) r/m byte by 2, once | sarb $1,%dl
sarb $1,(%ebx,1)
sarb $1,m8(%ebx,1)
sarb $1,m8(%ebx,%ebp,1) |
D2 /7 | sarb cl,r/m8 | 3/7 |
Signed divide^(1) r/m byte by 2, CL times | sarb %cl,%dl
sarb %cl,(%ebx,1)
sarb %cl,m8(%ebx,1)
sarb %cl,m8(%ebx,%ebp,1) |
C0 /7 ib | sarb imm8,r/m8 | 3/7 |
Signed divide^(1) r/m byte by 2, imm8 times | sarb $0x7f,%dl
sarb $0x7f,(%ebx,1)
sarb $0x7f,m8(%ebx,1)
sarb $0x7f,m8(%ebx,%ebp,1) |
D1 /7 | sarw 1,r/m16 | 3/7 |
Signed divide^(1) r/m word by 2, once | sarw $1,%cx
sarw $1,(%ebx,1)
sarw $1,(%ebx,2)
sarw $1,(%ebx,%ebp,1) |
D3 /7 | sarw cl,r/m16 | 3/7 |
Signed divide^(1) r/m word by 2, CL times | sarw %cl,%cx
sarw %cl,(%ebx,1)
sarw %cl,(%ebx,2)
sarw %cl,(%ebx,%ebp,1) |
C1 /7 ib | sarw imm8,r/m16 | 3/7 |
Signed divide^(1) r/m word by 2, imm8 times | sarw $0x7f,%cx
sarw $0x7f,(%ebx,1)
sarw $0x7f,(%ebx,2)
sarw $0x7f,(%ebx,%ebp,1) |
D1 /7 | sarl 1,r/m32 | 3/7 |
Signed divide^(1) r/m dword by 2, once | sarl $1,%ecx
sarl $1,(%ebx,2)
sarl $1,(%ebx,4)
sarl $1,(%ebx,%ebp,1) |
D3 /7 | sarl cl,r/m32 | 3/7 |
Signed divide^(1) r/m dword by 2, CL times | sarl %cl,%ecx
sarl %cl,(%ebx,2)
sarl %cl,(%ebx,4)
sarl %cl,(%ebx,%ebp,1) |
C1 /7 ib | sarl imm8,r/m32 | 3/7 |
Signed divide^(1) r/m dword by 2, imm8 times | sarl $0x7f,%ecx
sarl $0x7f,(%ebx,2)
sarl $0x7f,(%ebx,4)
sarl $0x7f,(%ebx,%ebp,1) |
D0 /4 | shlb 1,r/m8 | 3/7 |
Multiply r/m byte by 2, once | shlb $1,%dl
shlb $1,(%ebx,1)
shlb $1,m8(%ebx,1)
shlb $1,m8(%ebx,%ebp,1) |
D2 /4 | shlb cl,r/m8 | 3/7 |
Multiply r/m byte by 2, CL times | shlb %cl,%dl
shlb %cl,(%ebx,1)
shlb %cl,m8(%ebx,1)
shlb %cl,m8(%ebx,%ebp,1) |
C0 /4 ib | shlb imm8,r/m8 | 3/7 |
Multiply r/m byte by 2, imm8 times | shlb $0x7f,%dl
shlb $0x7f,(%ebx,1)
shlb $0x7f,m8(%ebx,1)
shlb $0x7f,m8(%ebx,%ebp,1) |
D1 /4 | shlw 1,r/m16 | 3/7 |
Multiply r/m word by 2, once | shlw $1,%cx
shlw $1,(%ebx,1)
shlw $1,(%ebx,2)
shlw $1,(%ebx,%ebp,1) |
D3 /4 | shlw cl,r/m16 | 3/7 |
Multiply r/m word by 2, CL times | shlw %cl,%cx
shlw %cl,(%ebx,1)
shlw %cl,(%ebx,2)
shlw %cl,(%ebx,%ebp,1) |
C1 /4 ib | shlw imm8,r/m16 | 3/7 |
Multiply r/m word by 2, imm8 times | shlw $0x7f,%cx
shlw $0x7f,(%ebx,1)
shlw $0x7f,(%ebx,2)
shlw $0x7f,(%ebx,%ebp,1) |
D1 /4 | shll 1,r/m32 | 3/7 |
Multiply r/m dword by 2, once | shll $1,%ecx
shll $1,(%ebx,2)
shll $1,(%ebx,4)
shll $1,(%ebx,%ebp,1) |
D3 /4 | shll cl,r/m32 | 3/7 |
Multiply r/m dword by 2, CL times | shll %cl,%ecx
shll %cl,(%ebx,2)
shll %cl,(%ebx,4)
shll %cl,(%ebx,%ebp,1) |
C1 /4 ib | shll imm8,r/m32 | 3/7 |
Multiply r/m dword by 2, imm8 times | shll $0x7f,%ecx
shll $0x7f,(%ebx,2)
shll $0x7f,(%ebx,4)
shll $0x7f,(%ebx,%ebp,1) |
D0 /5 | shrb 1,r/m8 | 3/7 |
Unsigned divide r/m byte by 2, once | shrb $1,%dl
shrb $1,(%ebx,1)
shrb $1,m8(%ebx,1)
shrb $1,m8(%ebx,%ebp,1) |
D2 /5 | shrb cl,r/m8 | 3/7 |
Unsigned divide r/m byte by 2, CL times | shrb %cl,%dl
shrb %cl,(%ebx,1)
shrb %cl,m8(%ebx,1)
shrb %cl,m8(%ebx,%ebp,1) |
C0 /5 ib | shrb imm8,r/m8 | 3/7 |
Unsigned divide r/m byte by 2, imm8 times | shrb $0x7f,%dl
shrb $0x7f,(%ebx,1)
shrb $0x7f,m8(%ebx,1)
shrb $0x7f,m8(%ebx,%ebp,1) |
D1 /5 | shrw 1,r/m16 | 3/7 |
Unsigned divide r/m word by 2, once | shrw $1,%cx
shrw $1,(%ebx,1)
shrw $1,(%ebx,2)
shrw $1,(%ebx,%ebp,1) |
D3 /5 | shrw cl,r/m16 | 3/7 |
Unsigned divide r/m word by 2, CL times | shrw %cl,%cx
shrw %cl,(%ebx,1)
shrw %cl,(%ebx,2)
shrw %cl,(%ebx,%ebp,1) |
C1 /5 ib | shrw imm8,r/m16 | 3/7 |
Unsigned divide r/m word by 2, imm8 times | shrw $0x7f,%cx
shrw $0x7f,(%ebx,1)
shrw $0x7f,(%ebx,2)
shrw $0x7f,(%ebx,%ebp,1) |
D1 /5 | shrl 1,r/m32 | 3/7 |
Unsigned divide r/m dword by 2, once | shrl $1,%ecx
shrl $1,(%ebx,2)
shrl $1,(%ebx,4)
shrl $1,(%ebx,%ebp,1) |
D3 /5 | shrl cl,r/m32 | 3/7 |
Unsigned divide r/m dword by 2, CL times | shrl %cl,%ecx
shrl %cl,(%ebx,2)
shrl %cl,(%ebx,4)
shrl %cl,(%ebx,%ebp,1) |
C1 /5 ib | shrl imm8,r/m32 | 3/7 |
Unsigned divide r/m dword by 2, imm8 times | shrl $0x7f,%ecx
shrl $0x7f,(%ebx,2)
shrl $0x7f,(%ebx,4)
shrl $0x7f,(%ebx,%ebp,1) |
Not the same division as IDIV; rounding is toward negative infinity.
Operation
(* COUNT is the second parameter *)
(temp) := COUNT;
WHILE (temp <> 0)
DO
IF instruction is SAL or SHL
THEN CF := high-order bit of r/m;
FI;
IF instruction is SAR or SHR
THEN CF := low-order bit of r/m;
FI;
IF instruction = SAL or SHL
THEN r/m := r/m * 2;
FI;
IF instruction = SAR
THEN r/m := r/m /2 (*Signed divide, rounding toward negative infinity*);
FI;
IF instruction = SHR
THEN r/m := r/m / 2; (* Unsigned divide *);
FI;
temp := temp - 1;
OD;
(* Determine overflow for the various instructions *)
IF COUNT = 1
THEN
IF instruction is SAL or SHL
THEN OF := high-order bit of r/m <> (CF);
FI;
IF instruction is SAR
THEN OF := 0;
FI;
IF instruction is SHR
THEN OF := high-order bit of operand;
FI;
ELSE OF := undefined;
FI;
Description SAL (or its synonym, SHL) shifts the bits
of the operand upward. The high-order bit is shifted into the carry
flag, and the low-order bit is set to 0. SAR and SHR shift the bits of the operand downward. The
low-order bit is shifted into the carry flag. The effect is to divide
the operand by 2. SAR performs a signed divide with rounding toward
negative infinity (not the same as IDIV); the high-order bit remains the same. SHR performs an unsigned divide; the high-order bit is set to 0.
The
shift is repeated the number of times indicated by the second operand,
which is either an immediate number or the contents of the CL register.
To reduce the maximum execution time, the 80386 does not allow shift
counts greater than 31. If a shift count greater than 31 is attempted,
only the bottom five bits of the shift count are used. (The 8086 uses
all eight bits of the shift count.) The overflow flag is set only if the single-shift forms of
the instructions are used. For left shifts, OF is set to 0 if the high
bit of the answer is the same as the result of the carry flag (i.e.,
the top two bits of the original operand were the same); OF is set to 1
if they are different. For SAR, OF is set to 0 for all single shifts.
For SHR, OF is set to the high-order bit of the original operand. Flags Affected
OF for single shifts; OF is undefined for multiple shifts; CF, ZF, PF, and SF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
SBB -- Integer Subtraction with Borrow
Opcode | Instruction | Clocks |
Description | Example |
1C ib | sbbb imm8,al | 2 |
Subtract with borrow immediate byte from AL | sbbb $0x7f,%al |
1D iw | sbbw imm16,ax | 2 |
Subtract with borrow immediate word from AX | sbbw $0x7fff,%ax |
1D id | sbbl imm32,eax | 2 |
Subtract with borrow immediate dword from EAX | sbbl $0x7fffffff,%eax |
80 /3 ib | sbbb imm8,r/m8 | 2/7 |
Subtract with borrow immediate byte from r/m byte | sbbb $0x7f,%dl
sbbb $0x7f,(%ebx,1)
sbbb $0x7f,m8(%ebx,1)
sbbb $0x7f,m8(%ebx,%ebp,1) |
81 /3 iw | sbbw imm16,r/m16 | 2/7 |
Subtract with borrow immediate word from r/m word | sbbw $0x7fff,%cx
sbbw $0x7fff,(%ebx,1)
sbbw $0x7fff,(%ebx,2)
sbbw $0x7fff,(%ebx,%ebp,1) |
81 /3 id | sbbl imm32,r/m32 | 2/7 |
Subtract with borrow immediate dword from r/m dword | sbbl $0x7fffffff,%ecx
sbbl $0x7fffffff,(%ebx,2)
sbbl $0x7fffffff,(%ebx,4)
sbbl $0x7fffffff,(%ebx,%ebp,1) |
83 /3 ib | sbbw imm8,r/m16 | 2/7 |
Subtract with borrow sign-extended immediate byte from r/m word | sbbw $0x7f,%cx
sbbw $0x7f,(%ebx,1)
sbbw $0x7f,(%ebx,2)
sbbw $0x7f,(%ebx,%ebp,1) |
83 /3 ib | sbbl imm8,r/m32 | 2/7 |
Subtract with borrow sign-extended immediate byte from r/m dword | sbbl $0x7f,%ecx
sbbl $0x7f,(%ebx,2)
sbbl $0x7f,(%ebx,4)
sbbl $0x7f,(%ebx,%ebp,1) |
18 /r | sbbb r8,r/m8 | 2/6 |
Subtract with borrow byte register from r/m byte | sbbb %bh,%dl
sbbb %bh,(%ebx,1)
sbbb %bh,m8(%ebx,1)
sbbb %bh,m8(%ebx,%ebp,1) |
19 /r | sbbw r16,r/m16 | 2/6 |
Subtract with borrow word register from r/m word | sbbw %bx,%cx
sbbw %bx,(%ebx,1)
sbbw %bx,(%ebx,2)
sbbw %bx,(%ebx,%ebp,1) |
19 /r | sbbl r32,r/m32 | 2/6 |
Subtract with borrow dword register from r/m dword | sbbl %ebx,%ecx
sbbl %ebx,(%ebx,2)
sbbl %ebx,(%ebx,4)
sbbl %ebx,(%ebx,%ebp,1) |
1A /r | sbbb r/m8,r8 | 2/7 |
Subtract with borrow byte register from r/m byte | sbbb %dl,%bh
sbbb (%ebx,1),%bh
sbbb m8(%ebx,1),%bh
sbbb m8(%ebx,%ebp,1),%bh |
1B /r | sbbw r/m16,r16 | 2/7 |
Subtract with borrow word register from r/m word | sbbw %cx,%bx
sbbw (%ebx,1),%bx
sbbw (%ebx,2),%bx
sbbw (%ebx,%ebp,1),%bx |
1B /r | sbbl r/m32,r32 | 2/7 |
Subtract with borrow dword register from r/m dword | sbbl %ecx,%ebx
sbbl (%ebx,2),%ebx
sbbl (%ebx,4),%ebx
sbbl (%ebx,%ebp,1),%ebx |
Operation
IF SRC is a byte and DEST is a word or dword
THEN DEST := DEST - (SignExtend(SRC) + CF)
ELSE DEST := DEST - (SRC + CF);
Description SBB adds the second operand (DEST) to the
carry flag (CF) and subtracts the result from the first operand (SRC).
The result of the subtraction is assigned to the first operand (DEST),
and the flags are set accordingly. When an immediate byte value is subtracted from a word operand, the immediate value is first sign-extended.
Flags Affected
OF, SF, ZF, AF, PF, and CF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
SCAS/SCASB/SCASW/SCASD -- Compare String Data
Opcode | Instruction | Clocks |
Description | Example |
AE | scasb | 7 |
Compare bytes AL-ES:[DI], update (E)DI | scasb |
AF | scasw | 7 |
Compare words AX-ES:[DI], update (E)DI | scasw |
AF | scasl | 7 |
Compare dwords EAX-ES:[DI], update (E)DI | scasl |
Operation
IF AddressSize = 16
THEN use DI for dest-index;
ELSE (* AddressSize = 32 *) use EDI for dest-index;
FI;
IF byte type of instruction
THEN
AL - [dest-index]; (* Compare byte in AL and dest *)
IF DF = 0 THEN IndDec := 1 ELSE IncDec := -1; FI;
ELSE
IF OperandSize = 16
THEN
AX - [dest-index]; (* compare word in AL and dest *)
IF DF = 0 THEN IncDec := 2 ELSE IncDec := -2; FI;
ELSE (* OperandSize = 32 *)
EAX - [dest-index];(* compare dword in EAX & dest *)
IF DF = 0 THEN IncDec := 4 ELSE IncDec := -4; FI;
FI;
FI;
dest-index := dest-index + IncDec
Description SCAS subtracts the memory byte or word at
the destination register from the AL, AX or EAX register. The result is
discarded; only the flags are set. The operand must be addressable from
the ES segment; no segment override is possible. If the address-size attribute for this instruction is 16 bits,
DI is used as the destination register; otherwise, the address-size
attribute is 32 bits and EDI is used. The address of the memory data being compared is determined
solely by the contents of the destination register, not by the operand
to SCAS. The operand validates ES segment addressability and determines
the data type. Load the correct index value into DI or EDI before
executing SCAS. After the comparison is made, the destination register is automatically updated. If the direction flag is 0 (CLD was executed), the destination register is incremented; if the direction flag is 1 (STD
was executed), it is decremented. The increments or decrements are by 1
if bytes are compared, by 2 if words are compared, or by 4 if
doublewords are compared. SCASB, SCASW, and SCASD are synonyms for the byte, word and
doubleword SCAS instructions that don't require operands. They are
simpler to code, but provide no type or segment checking. SCAS can be preceded by the REPE or REPNE prefix for a block search of CX or ECX bytes or words. Refer to the REP instruction for further details.
Flags Affected
OF, SF, ZF, AF, PF, and CF as described in Appendix C
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS
segment; #PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
SETcc -- Byte Set on Condition
Opcode | Instruction | Clocks |
Description | Example |
0F 97 | setab r/m8 | 4/5 |
Set byte if above (CF=0 and ZF=0) | setab %dl
setab (%ebx,1)
setab m8(%ebx,1)
setab m8(%ebx,%ebp,1) |
0F 93 | setaeb r/m8 | 4/5 |
Set byte if above or equal (CF=0) | setaeb %dl
setaeb (%ebx,1)
setaeb m8(%ebx,1)
setaeb m8(%ebx,%ebp,1) |
0F 92 | setbb r/m8 | 4/5 |
Set byte if below (CF=1) | setbb %dl
setbb (%ebx,1)
setbb m8(%ebx,1)
setbb m8(%ebx,%ebp,1) |
0F 96 | setbeb r/m8 | 4/5 |
Set byte if below or equal (CF=1 or (ZF=1) | setbeb %dl
setbeb (%ebx,1)
setbeb m8(%ebx,1)
setbeb m8(%ebx,%ebp,1) |
0F 92 | setcb r/m8 | 4/5 |
Set if carry (CF=1) | setcb %dl
setcb (%ebx,1)
setcb m8(%ebx,1)
setcb m8(%ebx,%ebp,1) |
0F 94 | seteb r/m8 | 4/5 |
Set byte if equal (ZF=1) | seteb %dl
seteb (%ebx,1)
seteb m8(%ebx,1)
seteb m8(%ebx,%ebp,1) |
0F 9F | setgb r/m8 | 4/5 |
Set byte if greater (ZF=0 or SF=OF) | setgb %dl
setgb (%ebx,1)
setgb m8(%ebx,1)
setgb m8(%ebx,%ebp,1) |
0F 9D | setgeb r/m8 | 4/5 |
Set byte if greater or equal (SF=OF) | setgeb %dl
setgeb (%ebx,1)
setgeb m8(%ebx,1)
setgeb m8(%ebx,%ebp,1) |
0F 9C | setlb r/m8 | 4/5 |
Set byte if less (SF< | setlb %dl
setlb (%ebx,1)
setlb m8(%ebx,1)
setlb m8(%ebx,%ebp,1) |
0F 9E | setleb r/m8 | 4/5 |
Set byte if less or equal (ZF=1 and SF< | setleb %dl
setleb (%ebx,1)
setleb m8(%ebx,1)
setleb m8(%ebx,%ebp,1) |
0F 96 | setnab r/m8 | 4/5 |
Set byte if not above (CF=1) | setnab %dl
setnab (%ebx,1)
setnab m8(%ebx,1)
setnab m8(%ebx,%ebp,1) |
0F 92 | setnaeb r/m8 | 4/5 |
Set byte if not above or equal (CF=1) | setnaeb %dl
setnaeb (%ebx,1)
setnaeb m8(%ebx,1)
setnaeb m8(%ebx,%ebp,1) |
0F 93 | setnbb r/m8 | 4/5 |
Set byte if not below (CF=0) | setnbb %dl
setnbb (%ebx,1)
setnbb m8(%ebx,1)
setnbb m8(%ebx,%ebp,1) |
0F 97 | setnbeb r/m8 | 4/5 |
Set byte if not below or equal (CF=0 and ZF=0) | setnbeb %dl
setnbeb (%ebx,1)
setnbeb m8(%ebx,1)
setnbeb m8(%ebx,%ebp,1) |
0F 93 | setncb r/m8 | 4/5 |
Set byte if not carry (CF=0) | setncb %dl
setncb (%ebx,1)
setncb m8(%ebx,1)
setncb m8(%ebx,%ebp,1) |
0F 95 | setneb r/m8 | 4/5 |
Set byte if not equal (ZF=0) | setneb %dl
setneb (%ebx,1)
setneb m8(%ebx,1)
setneb m8(%ebx,%ebp,1) |
0F 9E | setngb r/m8 | 4/5 |
Set byte if not greater (ZF=1 or SF< | setngb %dl
setngb (%ebx,1)
setngb m8(%ebx,1)
setngb m8(%ebx,%ebp,1) |
0F 9C | setngeb r/m8 | 4/5 |
Set if not greater or equal (SF< | setngeb %dl
setngeb (%ebx,1)
setngeb m8(%ebx,1)
setngeb m8(%ebx,%ebp,1) |
0F 9D | setnlb r/m8 | 4/5 |
Set byte if not less (SF=OF) | setnlb %dl
setnlb (%ebx,1)
setnlb m8(%ebx,1)
setnlb m8(%ebx,%ebp,1) |
0F 9F | setnleb r/m8 | 4/5 |
Set byte if not less or equal (ZF=1 and SF< | setnleb %dl
setnleb (%ebx,1)
setnleb m8(%ebx,1)
setnleb m8(%ebx,%ebp,1) |
0F 91 | setnob r/m8 | 4/5 |
Set byte if not overflow (OF=0) | setnob %dl
setnob (%ebx,1)
setnob m8(%ebx,1)
setnob m8(%ebx,%ebp,1) |
0F 9B | setnpb r/m8 | 4/5 |
Set byte if not parity (PF=0) | setnpb %dl
setnpb (%ebx,1)
setnpb m8(%ebx,1)
setnpb m8(%ebx,%ebp,1) |
0F 99 | setnsb r/m8 | 4/5 |
Set byte if not sign (SF=0) | setnsb %dl
setnsb (%ebx,1)
setnsb m8(%ebx,1)
setnsb m8(%ebx,%ebp,1) |
0F 95 | setnzb r/m8 | 4/5 |
Set byte if not zero (ZF=0) | setnzb %dl
setnzb (%ebx,1)
setnzb m8(%ebx,1)
setnzb m8(%ebx,%ebp,1) |
0F 90 | setob r/m8 | 4/5 |
Set byte if overflow (OF=1) | setob %dl
setob (%ebx,1)
setob m8(%ebx,1)
setob m8(%ebx,%ebp,1) |
0F 9A | setpb r/m8 | 4/5 |
Set byte if parity (PF=1) | setpb %dl
setpb (%ebx,1)
setpb m8(%ebx,1)
setpb m8(%ebx,%ebp,1) |
0F 9A | setpeb r/m8 | 4/5 |
Set byte if parity even (PF=1) | setpeb %dl
setpeb (%ebx,1)
setpeb m8(%ebx,1)
setpeb m8(%ebx,%ebp,1) |
0F 9B | setpob r/m8 | 4/5 |
Set byte if parity odd (PF=0) | setpob %dl
setpob (%ebx,1)
setpob m8(%ebx,1)
setpob m8(%ebx,%ebp,1) |
0F 98 | setsb r/m8 | 4/5 |
Set byte if sign (SF=1) | setsb %dl
setsb (%ebx,1)
setsb m8(%ebx,1)
setsb m8(%ebx,%ebp,1) |
0F 94 | setzb r/m8 | 4/5 |
Set byte if zero (ZF=1) | setzb %dl
setzb (%ebx,1)
setzb m8(%ebx,1)
setzb m8(%ebx,%ebp,1) |
Operation
IF condition THEN r/m8 := 1 ELSE r/m8 := 0; FI;
Description SETcc stores a byte at the destination
specified by the effective address or register if the condition is met,
or a 0 byte if the condition is not met. Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a non-writable segment; #GP(0) for an
illegal memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
SGDT/SIDT -- Store Global/Interrupt Descriptor Table Register
Opcode | Instruction | Clocks |
Description | Example |
0F 01 /0 | sgdt m | 9 |
Store GDTR to m | sgdt m |
0F 01 /1 | sidt m | 9 |
Store IDTR to m | sidt m |
Operation
DEST := 48-bit BASE/LIMIT register contents;
Description SGDT/SIDT copies the contents of the
descriptor table register the six bytes of memory indicated by the
operand. The LIMIT field of the register is assigned to the first word
at the effective address. If the operand-size attribute is 32 bits, the
next three bytes are assigned the BASE field of the register, and the
fourth byte is written with zero. The last byte is undefined.
Otherwise, if the operand-size attribute is 16 bits, the next four
bytes are assigned the 32-bit BASE field of the register. SGDT and SIDT are used only in operating system software; they are not used in application programs.
Flags Affected
None
Protected Mode Exceptions
Interrupt 6 if the destination operand is a register; #GP(0) if the
destination is in a nonwritable segment; #GP(0) for an illegal memory
operand effective address in the CS, DS, ES, FS, or GS segments; #SS(0)
for an illegal address in the SS segment; #PF(fault-code) for a page
fault Real Address Mode Exceptions Interrupt 6 if the
destination operand is a register; Interrupt 13 if any part of the
operand would lie outside of the effective address space from 0 to
0FFFFH Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
Compatability Note
The 16-bit forms of the SGDT/SIDT instructions are compatible with the
80286, if the value in the upper eight bits is not referenced. The
80286 stores 1's in these upper bits, whereas the 80386 stores 0's if
the operand-size attribute is 16 bits. These bits were specified as
undefined by the SGDT/SIDT instructions in the iAPX 286 Programmer's
Reference Manual.
SHLD -- Double Precision Shift Left
Opcode | Instruction | Clocks |
Description | Example |
0F A4 | shldw r16,r/m16 | 3/7 |
r/m16 gets SHL of r/m16 concatenated with r16 | shldw %bx,%cx
shldw %bx,(%ebx,1)
shldw %bx,(%ebx,2)
shldw %bx,(%ebx,%ebp,1) |
0F A4 | shldl r32,r/m32 | 3/7 |
r/m32 gets SHL of r/m32 concatenated with r32 | shldl %ebx,%ecx
shldl %ebx,(%ebx,2)
shldl %ebx,(%ebx,4)
shldl %ebx,(%ebx,%ebp,1) |
0F A5 | shldw r16,r/m16 | 3/7 |
r/m16 gets SHL of r/m16 concatenated with r16 | shldw %bx,%cx
shldw %bx,(%ebx,1)
shldw %bx,(%ebx,2)
shldw %bx,(%ebx,%ebp,1) |
0F A5 | shldl r32,r/m32 | 3/7 |
r/m32 gets SHL of r/m32 concatenated with r32 | shldl %ebx,%ecx
shldl %ebx,(%ebx,2)
shldl %ebx,(%ebx,4)
shldl %ebx,(%ebx,%ebp,1) |
Operation
(* count is an unsigned integer corresponding to the last operand of the
instruction, either an immediate byte or the byte in register CL *)
ShiftAmt := count MOD 32;
inBits := register; (* Allow overlapped operands *)
IF ShiftAmt = 0
THEN no operation
ELSE
IF ShiftAmt >= OperandSize
THEN (* Bad parameters *)
r/m := UNDEFINED;
CF, OF, SF, ZF, AF, PF := UNDEFINED;
ELSE (* Perform the shift *)
CF := BIT[Base, OperandSize - ShiftAmt];
(* Last bit shifted out on exit *)
FOR i := OperandSize - 1 DOWNTO ShiftAmt
DO
BIT[Base, i] := BIT[Base, i - ShiftAmt];
OF;
FOR i := ShiftAmt - 1 DOWNTO 0
DO
BIT[Base, i] := BIT[inBits, i - ShiftAmt + OperandSize];
OD;
Set SF, ZF, PF (r/m);
(* SF, ZF, PF are set according to the value of the result *)
AF := UNDEFINED;
FI;
FI;
Description SHLD shifts the first operand provided by
the r/m field to the left as many bits as specified by the count
operand. The second operand (r16 or r32) provides the bits to shift in
from the right (starting with bit 0). The result is stored back into
the r/m operand. The register remains unaltered. The count operand is provided by either an immediate byte or the
contents of the CL register. These operands are taken MODULO 32 to
provide a number between 0 and 31 by which to shift. Because the bits
to shift are provided by the specified registers, the operation is
useful for multiprecision shifts (64 bits or more). The SF, ZF and PF
flags are set according to the value of the result. CS is set to the
value of the last bit shifted out. OF and AF are left undefined. Flags Affected
OF, SF, ZF, PF, and CF as described above; AF and OF are undefined
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
SHRD -- Double Precision Shift Right
Opcode | Instruction | Clocks |
Description | Example |
0F AC | shrdw r16,r/m16 | 3/7 |
r/m16 gets SHR of r/m16 concatenated with r16 | shrdw %bx,%cx
shrdw %bx,(%ebx,1)
shrdw %bx,(%ebx,2)
shrdw %bx,(%ebx,%ebp,1) |
0F AC | shrdl r32,r/m32 | 3/7 |
r/m32 gets SHR of r/m32 concatenated with r32 | shrdl %ebx,%ecx
shrdl %ebx,(%ebx,2)
shrdl %ebx,(%ebx,4)
shrdl %ebx,(%ebx,%ebp,1) |
0F AD | shrdw r16,r/m16 | 3/7 |
r/m16 gets SHR of r/m16 concatenated with r16 | shrdw %bx,%cx
shrdw %bx,(%ebx,1)
shrdw %bx,(%ebx,2)
shrdw %bx,(%ebx,%ebp,1) |
0F AD | shrdl r32,r/m32 | 3/7 |
r/m32 gets SHR of r/m32 concatenated with r32 | shrdl %ebx,%ecx
shrdl %ebx,(%ebx,2)
shrdl %ebx,(%ebx,4)
shrdl %ebx,(%ebx,%ebp,1) |
Operation
(* count is an unsigned integer corresponding to the last operand of the
instruction, either an immediate byte or the byte in register CL *)
ShiftAmt := count MOD 32;
inBits := register; (* Allow overlapped operands *)
IF ShiftAmt = 0
THEN no operation
ELSE
IF ShiftAmt >= OperandSize
THEN (* Bad parameters *)
r/m := UNDEFINED;
CF, OF, SF, ZF, AF, PF := UNDEFINED;
ELSE (* Perform the shift *)
CF := BIT[r/m, ShiftAmt - 1]; (* last bit shifted out on exit *)
FOR i := 0 TO OperandSize - 1 - ShiftAmt
DO
BIT[r/m, i] := BIT[r/m, i - ShiftAmt];
OD;
FOR i := OperandSize - ShiftAmt TO OperandSize - 1
DO
BIT[r/m,i] := BIT[inBits,i+ShiftAmt - OperandSize];
OD;
Set SF, ZF, PF (r/m);
(* SF, ZF, PF are set according to the value of the result *)
Set SF, ZF, PF (r/m);
AF := UNDEFINED;
FI;
FI;
Description SHRD shifts the first operand provided by
the r/m field to the right as many bits as specified by the count
operand. The second operand (r16 or r32) provides the bits to shift in
from the left (starting with bit 31). The result is stored back into
the r/m operand. The register remains unaltered. The count operand is provided by either an immediate byte or the
contents of the CL register. These operands are taken MODULO 32 to
provide a number between 0 and 31 by which to shift. Because the bits
to shift are provided by the specified register, the operation is
useful for multi-precision shifts (64 bits or more). The SF, ZF and PF
flags are set according to the value of the result. CS is set to the
value of the last bit shifted out. OF and AF are left undefined. Flags Affected
OF, SF, ZF, PF, and CF as described above; AF and OF are undefined
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
SLDT -- Store Local Descriptor Table Register
Opcode | Instruction | Clocks |
Description | Example |
0F 00 /0 | sldtw r/m16 | pm=2/2 |
Store LDTR to EA word | sldtw %cx
sldtw (%ebx,1)
sldtw (%ebx,2)
sldtw (%ebx,%ebp,1) |
Operation
r/m16 := LDTR;
Description SLDT stores the Local Descriptor Table
Register (LDTR) in the two-byte register or memory location indicated
by the effective address operand. This register is a selector that
points into the Global Descriptor Table. SLDT is used only in operating system software. It is not used in application programs.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 6; SLDT is not recognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
Notes
The operand-size attribute has no effect on the operation of the instruction.
SMSW -- Store Machine Status Word
Opcode | Instruction | Clocks |
Description | Example |
0F 01 /4 | smsww r/m16 | 2/3,pm=2/2 |
Store machine status word to EA word | smsww %cx
smsww (%ebx,1)
smsww (%ebx,2)
smsww (%ebx,%ebp,1) |
Operation
r/m16 := MSW;
Description SMSW stores the machine status word (part
of CR0) in the two-byte register or memory location indicated by the
effective address operand. Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
Notes
This instruction is provided for compatibility with the 80286; 80386 programs should use MOV ..., CR0.
STC -- Set Carry Flag
Opcode | Instruction | Clocks |
Description | Example |
F9 | stc | 2 |
Set carry flag | stc |
Operation
CF := 1;
Description
STC sets the carry flag to 1.
Flags Affected
CF := 1
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
STD -- Set Direction Flag
Opcode | Instruction | Clocks |
Description | Example |
FD | std | 2 |
Set direction flag so (E)SI and/or (E)DI decrement | std |
Operation
DF := 1;
Description STD sets the direction flag to 1, causing
all subsequent string operations to decrement the index registers,
(E)SI and/or (E)DI, on which they operate. Flags Affected
DF := 1
Protected Mode Exceptions
None
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
STI -- Set Interrupt Flag
Opcode | Instruction | Clocks |
Description | Example |
F13 | sti | 3 |
Set interrupt flag | sti |
Operation
IF := 1
Description STI sets the interrupt flag to 1. The
80386 then responds to external interrupts after executing the next
instruction if the next instruction allows the interrupt flag to remain
enabled. If external interrupts are disabled and you code STI, RET (such as at the end of a subroutine), the RET is allowed to execute before external interrupts are recognized. Also, if external interrupts are disabled and you code STI, CLI, then external interrupts are not recognized because the CLI instruction clears the interrupt flag during its execution.
Flags Affected
IF := 1
Protected Mode Exceptions
#GP(0) if the current privilege level is greater (has less privilege) than the I/O privilege level
Real Address Mode Exceptions
None
Virtual 8086 Mode Exceptions
None
STOS/STOSB/STOSW/STOSD -- Store String Data
Opcode | Instruction | Clocks |
Description | Example |
AA | stosb | 4 |
Store AL in byte ES:[(E)DI], update (E)DI | stosb |
AB | stosw | 4 |
Store AX in word ES:[(E)DI], update (E)DI | stosw |
AB | stosl | 4 |
Store EAX in dword ES:[(E)DI], update (E)DI | stosl |
Operation
IF AddressSize = 16
THEN use ES:DI for DestReg
ELSE (* AddressSize = 32 *) use ES:EDI for DestReg;
FI;
IF byte type of instruction
THEN
(ES:DestReg) := AL;
IF DF = 0
THEN DestReg := DestReg + 1;
ELSE DestReg := DestReg - 1;
FI;
ELSE IF OperandSize = 16
THEN
(ES:DestReg) := AX;
IF DF = 0
THEN DestReg := DestReg + 2;
ELSE DestReg := DestReg - 2;
FI;
ELSE (* OperandSize = 32 *)
(ES:DestReg) := EAX;
IF DF = 0
THEN DestReg := DestReg + 4;
ELSE DestReg := DestReg - 4;
FI;
FI;
FI;
Description STOS transfers the contents of all AL,
AX, or EAX register to the memory byte or word given by the destination
register relative to the ES segment. The destination register is DI for
an address-size attribute of 16 bits or EDI for an address-size
attribute of 32 bits. The destination operand must be addressable from the ES register. A segment override is not possible.
The
address of the destination is determined by the contents of the
destination register, not by the explicit operand of STOS. This operand
is used only to validate ES segment addressability and to determine the
data type. Load the correct index value into the destination register
before executing STOS. After the transfer is made, DI is automatically updated. If the direction flag is 0 (CLD was executed), DI is incremented; if the direction flag is 1 (STD
was executed), DI is decremented. DI is incremented or decremented by 1
if a byte is stored, by 2 if a word is stored, or by 4 if a doubleword
is stored. STOSB, STOSW, and STOSD are synonyms for the byte, word, and
doubleword STOS instructions, that do not require an operand. They are
simpler to use, but provide no type or segment checking. STOS can be preceded by the REP prefix for a block fill of CX or ECX bytes, words, or doublewords. Refer to the REP instruction for further details.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
STR -- Store Task Register
Opcode | Instruction | Clocks |
Description | Example |
0F 00 /1 | strw r/m16 | pm=23/27 |
Load EA word into task register | strw %cx
strw (%ebx,1)
strw (%ebx,2)
strw (%ebx,%ebp,1) |
Operation
r/m := task register;
Description The contents of the task register are
copied to the two-byte register or memory location indicated by the
effective address operand. STR is used only in operating system software. It is not used in application programs.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 6; STR is not recognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode
Notes
The operand-size attribute has no effect on this instruction.
SUB -- Integer Subtraction
Opcode | Instruction | Clocks |
Description | Example |
2C ib | subb imm8,al | 2 |
Subtract immediate byte from AL | subb $0x7f,%al |
2D iw | subw imm16,ax | 2 |
Subtract immediate word from AX | subw $0x7fff,%ax |
2D id | subl imm32,eax | 2 |
Subtract immediate dword from EAX | subl $0x7fffffff,%eax |
80 /5 ib | subb imm8,r/m8 | 2/7 |
Subtract immediate byte from r/m byte | subb $0x7f,%dl
subb $0x7f,(%ebx,1)
subb $0x7f,m8(%ebx,1)
subb $0x7f,m8(%ebx,%ebp,1) |
81 /5 iw | subw imm16,r/m16 | 2/7 |
Subtract immediate word from r/m word | subw $0x7fff,%cx
subw $0x7fff,(%ebx,1)
subw $0x7fff,(%ebx,2)
subw $0x7fff,(%ebx,%ebp,1) |
81 /5 id | subl imm32,r/m32 | 2/7 |
Subtract immediate dword from r/m dword | subl $0x7fffffff,%ecx
subl $0x7fffffff,(%ebx,2)
subl $0x7fffffff,(%ebx,4)
subl $0x7fffffff,(%ebx,%ebp,1) |
83 /5 ib | subw imm8,r/m16 | 2/7 |
Subtract sign-extended immediate byte from r/m word | subw $0x7f,%cx
subw $0x7f,(%ebx,1)
subw $0x7f,(%ebx,2)
subw $0x7f,(%ebx,%ebp,1) |
83 /5 ib | subl imm8,r/m32 | 2/7 |
Subtract sign-extended immediate byte from r/m dword | subl $0x7f,%ecx
subl $0x7f,(%ebx,2)
subl $0x7f,(%ebx,4)
subl $0x7f,(%ebx,%ebp,1) |
28 /r | subb r8,r/m8 | 2/6 |
Subtract byte register from r/m byte | subb %bh,%dl
subb %bh,(%ebx,1)
subb %bh,m8(%ebx,1)
subb %bh,m8(%ebx,%ebp,1) |
29 /r | subw r16,r/m16 | 2/6 |
Subtract word register from r/m word | subw %bx,%cx
subw %bx,(%ebx,1)
subw %bx,(%ebx,2)
subw %bx,(%ebx,%ebp,1) |
29 /r | subl r32,r/m32 | 2/6 |
Subtract dword register from r/m dword | subl %ebx,%ecx
subl %ebx,(%ebx,2)
subl %ebx,(%ebx,4)
subl %ebx,(%ebx,%ebp,1) |
2A /r | subb r/m8,r8 | 2/7 |
Subtract byte register from r/m byte | subb %dl,%bh
subb (%ebx,1),%bh
subb m8(%ebx,1),%bh
subb m8(%ebx,%ebp,1),%bh |
2B /r | subw r/m16,r16 | 2/7 |
Subtract word register from r/m word | subw %cx,%bx
subw (%ebx,1),%bx
subw (%ebx,2),%bx
subw (%ebx,%ebp,1),%bx |
2B /r | subl r/m32,r32 | 2/7 |
Subtract dword register from r/m dword | subl %ecx,%ebx
subl (%ebx,2),%ebx
subl (%ebx,4),%ebx
subl (%ebx,%ebp,1),%ebx |
Operation
IF SRC is a byte and DEST is a word or dword
THEN DEST := DEST - SignExtend(SRC);
ELSE DEST := DEST - SRC;
FI;
Description SUB subtracts the second operand (SRC)
from the first operand (DEST). The first operand is assigned the result
of the subtraction, and the flags are set accordingly. When an immediate byte value is subtracted from a word operand,
the immediate value is first sign-extended to the size of the
destination operand. Flags Affected
OF, SF, ZF, AF, PF, and CF as described in Appendix C
Protected Mode Exceptions
#GP(0) if the result is in a nonwritable segment; #GP(0) for an illegal
memory operand effective address in the CS, DS, ES, FS, or GS segments;
#SS(0) for an illegal address in the SS segment; #PF(fault-code) for a
page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
TEST -- Logical Compare
Opcode | Instruction | Clocks |
Description | Example |
A8 ib | testb imm8,al | 2 |
AND immediate byte with AL | testb $0x7f,%al |
A9 iw | testw imm16,ax | 2 |
AND immediate word with AX | testw $0x7fff,%ax |
A9 id | testl imm32,eax | 2 |
AND immediate dword with EAX | testl $0x7fffffff,%eax |
F6 /0 ib | testb imm8,r/m8 | 2/5 |
AND immediate byte with r/m byte | testb $0x7f,%dl
testb $0x7f,(%ebx,1)
testb $0x7f,m8(%ebx,1)
testb $0x7f,m8(%ebx,%ebp,1) |
F7 /0 iw | testw imm16,r/m16 | 2/5 |
AND immediate word with r/m word | testw $0x7fff,%cx
testw $0x7fff,(%ebx,1)
testw $0x7fff,(%ebx,2)
testw $0x7fff,(%ebx,%ebp,1) |
F7 /0 id | testl imm32,r/m32 | 2/5 |
AND immediate dword with r/m dword | testl $0x7fffffff,%ecx
testl $0x7fffffff,(%ebx,2)
testl $0x7fffffff,(%ebx,4)
testl $0x7fffffff,(%ebx,%ebp,1) |
84 /r | testb r8,r/m8 | 2/5 |
AND byte register with r/m byte | testb %bh,%dl
testb %bh,(%ebx,1)
testb %bh,m8(%ebx,1)
testb %bh,m8(%ebx,%ebp,1) |
85 /r | testw r16,r/m16 | 2/5 |
AND word register with r/m word | testw %bx,%cx
testw %bx,(%ebx,1)
testw %bx,(%ebx,2)
testw %bx,(%ebx,%ebp,1) |
85 /r | testl r32,r/m32 | 2/5 |
AND dword register with r/m dword | testl %ebx,%ecx
testl %ebx,(%ebx,2)
testl %ebx,(%ebx,4)
testl %ebx,(%ebx,%ebp,1) |
Operation
DEST := LeftSRC AND RightSRC;
CF := 0;
OF := 0;
Description TEST computes the bit-wise logical AND of
its two operands. Each bit of the result is 1 if both of the
corresponding bits of the operands are 1; otherwise, each bit is 0. The
result of the operation is discarded and only the flags are modified. Flags Affected
OF := 0, CF := 0; SF, ZF, and PF as described in Appendix C
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS
segment; #PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
VERR, VERW -- Verify a Segment for Reading or Writing
Opcode | Instruction | Clocks |
Description | Example |
0F 00 /4 | verrw r/m16 | pm=10/11 |
Set ZF=1 if segment can be read, selector in r/m16 | verrw %cx
verrw (%ebx,1)
verrw (%ebx,2)
verrw (%ebx,%ebp,1) |
0F 00 /5 | verww r/m16 | pm=15/16 |
Set ZF=1 if segment can be written, selector in r/m16 | verww %cx
verww (%ebx,1)
verww (%ebx,2)
verww (%ebx,%ebp,1) |
Operation
IF segment with selector at (r/m) is accessible
with current protection level
AND ((segment is readable for VERR) OR
(segment is writable for VERW))
THEN ZF := 0;
ELSE ZF := 1;
FI;
Description The two-byte register or memory operand
of VERR and VERW contains the value of a selector. VERR and VERW
determine whether the segment denoted by the selector is reachable from
the current privilege level and whether the segment is readable (VERR)
or writable (VERW). If the segment is accessible, the zero flag is set
to 1; if the segment is not accessible, the zero flag is set to 0. To
set ZF, the following conditions must be met:
- The selector must denote a descriptor within the bounds of the table (GDT or LDT); the selector must be "defined."
- The selector must denote the descriptor of a code or data segment (not that of a task state segment, LDT, or a gate).
- For VERR, the segment must be readable. For VERW, the segment must be a writable data segment.
- If
the code segment is readable and conforming, the descriptor privilege
level (DPL) can be any value for VERR. Otherwise, the DPL must be
greater than or equal to (have less or the same privilege as) both the
current privilege level and the selector's RPL.
The validation performed is the same as if the segment
were loaded into DS, ES, FS, or GS, and the indicated access (read or
write) were performed. The zero flag receives the result of the
validation. The selector's value cannot result in a protection
exception, enabling the software to anticipate possible segment access
problems. Flags Affected
ZF as described above
Protected Mode Exceptions
Faults generated by illegal addressing of the memory operand that
contains the selector, the selector is not loaded into any segment
register, and no faults attributable to the selector operand are
generated #GP(0) for an illegal memory operand effective address in the
CS, DS, ES, FS, or GS segments; #SS(0) for an illegal address in the SS
segment; #PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 6; VERR and VERW are not recognized in Real Address Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
WAIT -- Wait until BUSY# Pin is Inactive (HIGH)
Opcode | Instruction | Clocks |
Description | Example |
9B | wait | 6 min. |
Wait until BUSY pin is inactive (HIGH) | wait |
Description WAIT suspends execution of
80386 instructions until the BUSY# pin is inactive (high). The BUSY#
pin is driven by the 80287 numeric processor extension. Flags Affected
None
Protected Mode Exceptions
#NM if the task-switched flag in the machine status word (the lower 16
bits of register CR0) is set; #MF if the ERROR# input pin is asserted
(i.e., the 80287 has detected an unmasked numeric error) Real Address Mode Exceptions
Same exceptions as in Protected Mode
Virtual 8086 Mode Exceptions
Same exceptions as in Protected Mode
XCHG -- Exchange Register/Memory with Register
Opcode | Instruction | Clocks |
Description | Example |
90 + r | xchgw r16,ax | 3 |
Exchange word register with AX | xchgw %bx,%ax |
90 + r | xchgw ax,r16 | 3 |
Exchange word register with AX | xchgw %ax,%bx |
90 + r | xchgl r32,eax | 3 |
Exchange dword register with EAX | xchgl %ebx,%eax |
90 + r | xchgl eax,r32 | 3 |
Exchange dword register with EAX | xchgl %eax,%ebx |
86 /r | xchgb r8,r/m8 | 3 |
Exchange byte register with EA byte | xchgb %bh,%dl
xchgb %bh,(%ebx,1)
xchgb %bh,m8(%ebx,1)
xchgb %bh,m8(%ebx,%ebp,1) |
86 /r | xchgb r/m8,r8 | 3/5 |
Exchange byte register with EA byte | xchgb %dl,%bh
xchgb (%ebx,1),%bh
xchgb m8(%ebx,1),%bh
xchgb m8(%ebx,%ebp,1),%bh |
87 /r | xchgw r16,r/m16 | 3 |
Exchange word register with EA word | xchgw %bx,%cx
xchgw %bx,(%ebx,1)
xchgw %bx,(%ebx,2)
xchgw %bx,(%ebx,%ebp,1) |
87 /r | xchgw r/m16,r16 | 3/5 |
Exchange word register with EA word | xchgw %cx,%bx
xchgw (%ebx,1),%bx
xchgw (%ebx,2),%bx
xchgw (%ebx,%ebp,1),%bx |
87 /r | xchgl r32,r/m32 | 3 |
Exchange dword register with EA dword | xchgl %ebx,%ecx
xchgl %ebx,(%ebx,2)
xchgl %ebx,(%ebx,4)
xchgl %ebx,(%ebx,%ebp,1) |
87 /r | xchgl r/m32,r32 | 3/5 |
Exchange dword register with EA dword | xchgl %ecx,%ebx
xchgl (%ebx,2),%ebx
xchgl (%ebx,4),%ebx
xchgl (%ebx,%ebp,1),%ebx |
Operation
temp := DEST
DEST := SRC
SRC := temp
Description XCHG exchanges two operands. The operands
can be in either order. If a memory operand is involved, BUS LOCK is
asserted for the duration of the exchange, regardless of the presence
or absence of the LOCK prefix or of the value of the IOPL.
Flags Affected
None
Protected Mode Exceptions
#GP(0) if either operand is in a nonwritable segment; #GP(0) for an
illegal memory operand effective address in the CS, DS, ES, FS, or GS
segments; #SS(0) for an illegal address in the SS segment;
#PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
XLAT/XLATB -- Table Look-up Translation
D7 XLAT m8 5 Set AL to memory byte DS:[(E)BX + unsigned AL]
D7 XLATB 5 Set AL to memory byte DS:[(E)BX + unsigned AL]
Operation
IF AddressSize = 16
THEN
AL := (BX + ZeroExtend(AL))
ELSE (* AddressSize = 32 *)
AL := (EBX + ZeroExtend(AL));
FI;
Description XLAT changes the AL register from the
table index to the table entry. AL should be the unsigned index into a
table addressed by DS:BX (for an address-size attribute of 16 bits) or
DS:EBX (for an address-size attribute of 32 bits). The operand to XLAT allows for the possibility of a segment
override. XLAT uses the contents of BX even if they differ from the
offset of the operand. The offset of the operand should have been moved
intoBX/EBX with a previous instruction. The no-operand form, XLATB, can be used if the BX/EBX table will always reside in the DS segment.
Flags Affected
None
Protected Mode Exceptions
#GP(0) for an illegal memory operand effective address in the CS, DS,
ES, FS, or GS segments; #SS(0) for an illegal address in the SS
segment; #PF(fault-code) for a page fault Real Address Mode Exceptions
Interrupt 13 if any part of the operand would lie outside of the effective address space from 0 to 0FFFFH
Virtual 8086 Mode Exceptions
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
|