Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 Languages
 С
 GNU С Library 
 Qt 
 STL 
 Threads 
 C++ 
 Samples 
 stanford.edu 
 ANSI C
 Libs
 LD
 Socket
 Pusher
 Pipes
 Encryption
 Plugin
 Inter-Process
 Errors
 Deep C Secrets
 C + UNIX
 Linked Lists / Trees
 Asm
 Perl
 Python
 Shell
 Erlang
 Go
 Rust
 Алгоритмы
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 Linux Kernel 2.6...5170 
 Trees...940 
 Максвелл 3...870 
 Go Web ...823 
 William Gropp...803 
 Ethreal 3...787 
 Gary V.Vaughan-> Libtool...773 
 Ethreal 4...771 
 Rodriguez 6...763 
 Ext4 FS...755 
 Steve Pate 1...754 
 Clickhouse...753 
 Ethreal 1...742 
 Secure Programming for Li...731 
 C++ Patterns 3...716 
 Ulrich Drepper...696 
 Assembler...695 
 DevFS...661 
 Стивенс 9...649 
 MySQL & PosgreSQL...632 
 
  01.01.2024 : 3621733 посещений 

iakovlev.org

MOV -- Move Data

OpcodeInstructionClocks DescriptionExample
88 /rmovb r8,r/m82/2 Move byte register to r/m bytemovb %bh,%dl
movb %bh,(%ebx,1)
movb %bh,m8(%ebx,1)
movb %bh,m8(%ebx,%ebp,1)
89 /rmovw r16,r/m162/2 Move word register to r/m wordmovw %bx,%cx
movw %bx,(%ebx,1)
movw %bx,(%ebx,2)
movw %bx,(%ebx,%ebp,1)
89 /rmovl r32,r/m322/2 Move dword register to r/m dwordmovl %ebx,%ecx
movl %ebx,(%ebx,2)
movl %ebx,(%ebx,4)
movl %ebx,(%ebx,%ebp,1)
8A /rmovb r/m8,r82/4 Move r/m byte to byte registermovb %dl,%bh
movb (%ebx,1),%bh
movb m8(%ebx,1),%bh
movb m8(%ebx,%ebp,1),%bh
8B /rmovw r/m16,r162/4 Move r/m word to word registermovw %cx,%bx
movw (%ebx,1),%bx
movw (%ebx,2),%bx
movw (%ebx,%ebp,1),%bx
8B /rmovl r/m32,r322/4 Move r/m dword to dword registermovl %ecx,%ebx
movl (%ebx,2),%ebx
movl (%ebx,4),%ebx
movl (%ebx,%ebp,1),%ebx
8C /rmovw sreg,r/m162/2 Move segment register to r/m wordmovw %es,%cx
movw %es,(%ebx,1)
movw %es,(%ebx,2)
movw %es,(%ebx,%ebp,1)
8D /rmovw r/m16,sreg2/5,pm=18/19 Move r/m word to segment registermovw %cx,%es
movw (%ebx,1),%es
movw (%ebx,2),%es
movw (%ebx,%ebp,1),%es
A0movb moffs8,al4 Move byte at (seg:offset) to ALmovb farmem8,%al
A1movw moffs16,ax4 Move word at (seg:offset) to AXmovw farmem16,%ax
A1movl moffs32,eax4 Move dword at (seg:offset) to EAXmovl farmem32,%eax
A2movb al,moffs82 Move AL to (seg:offset)movb %al,farmem8
A3movw ax,moffs162 Move AX to (seg:offset)movw %ax,farmem16
A3movl eax,moffs322 Move EAX to (seg:offset)movl %eax,farmem32
B0 + rbmovb imm8,reg82 Move immediate byte to registermovb $0x7f,%ch
B8 + rwmovw imm16,reg162 Move immediate word to registermovw $0x7fff,%cx
B8 + rdmovl imm32,reg322 Move immediate dword to registermovl $0x7fffffff,%ecx
C6movb imm8,r/m82/2 Move immediate byte to r/m bytemovb $0x7f,%dl
movb $0x7f,(%ebx,1)
movb $0x7f,m8(%ebx,1)
movb $0x7f,m8(%ebx,%ebp,1)
C7movw imm16,r/m162/2 Move immediate word to r/m wordmovw $0x7fff,%cx
movw $0x7fff,(%ebx,1)
movw $0x7fff,(%ebx,2)
movw $0x7fff,(%ebx,%ebp,1)
C7movl imm32,r/m322/2 Move immediate dword to r/m dwordmovl $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

OpcodeInstructionClocks DescriptionExample
0F 20 /rmovl cr0/cr2/cr3,r326 Move (control register) to (register)movl %cr0,%ebx
movl %cr2,%ebx
movl %cr3,%ebx
0F 22 /rmovl r32,cr0/cr2/cr310/4/5 Move (register) to (control register)movl %ebx,%cr0
movl %ebx,%cr2
movl %ebx,%cr3
0F 21 /rmovl dr0-3,r3222 Move (debug register) to (register)movl %dr0,%ebx
0F 21 /rmovl dr6/dr7,r3214 Move (debug register) to (register)movl %dr6,%ebx
movl %dr7,%ebx
0F 23 /rmovl r32,dr0-322 Move (register) to (debug register)movl %ebx,%dr0
0F 23 /rmovl r32,dr6/dr716 Move (register) to (debug register)movl %ebx,%dr6
movl %ebx,%dr7
0F 24 /rmovl tr6/tr7,r3212 Move (test register) to (register)movl %tr6,%ebx
movl %tr7,%ebx
0F 26 /rmovl r32,tr6/tr712 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

OpcodeInstructionClocks DescriptionExample
A4movsb 7 Move byte DS:[(E)SI] to ES:[(E)DI]movsb
A5movsw 7 Move word DS:[(E)SI] to ES:[(E)DI]movsw
A5movsl 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

OpcodeInstructionClocks DescriptionExample
0F BE /rmovsx r/m8,r163/6 Move byte to word with sign-extendmovsx %dl,%bx
movsx (%ebx,1),%bx
movsx m8(%ebx,1),%bx
movsx m8(%ebx,%ebp,1),%bx
0F BE /rmovsx r/m8,r323/6 Move byte to dword, sign-extendmovsx %dl,%ebx
movsx (%ebx,1),%ebx
movsx m8(%ebx,1),%ebx
movsx m8(%ebx,%ebp,1),%ebx
0F BF /rmovsx r/m16,r323/6 Move word to dword, sign-extendmovsx %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

OpcodeInstructionClocks DescriptionExample
0F B6 /rmovzx r/m8,r163/6 Move byte to word with zero-extendmovzx %dl,%bx
movzx (%ebx,1),%bx
movzx m8(%ebx,1),%bx
movzx m8(%ebx,%ebp,1),%bx
0F B6 /rmovzx r/m8,r323/6 Move byte to dword, zero-extendmovzx %dl,%ebx
movzx (%ebx,1),%ebx
movzx m8(%ebx,1),%ebx
movzx m8(%ebx,%ebp,1),%ebx
0F B7 /rmovzx r/m16,r323/6 Move word to dword, zero-extendmovzx %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

OpcodeInstructionClocks DescriptionExample
F6 /4mulb r/m8,al9-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 /4mulw r/m16,ax9-22/12-25 Unsigned multiply (DX:AX := AX * r/m word)mulw %cx
mulw (%ebx,1)
mulw (%ebx,2)
mulw (%ebx,%ebp,1)
F7 /4mull r/m32,eax9-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

OpcodeInstructionClocks DescriptionExample
F6 /3negb r/m82/6 Two's complement negate r/m bytenegb %dl
negb (%ebx,1)
negb m8(%ebx,1)
negb m8(%ebx,%ebp,1)
F7 /3negw r/m162/6 Two's complement negate r/m wordnegw %cx
negw (%ebx,1)
negw (%ebx,2)
negw (%ebx,%ebp,1)
F7 /3negl r/m322/6 Two's complement negate r/m dwordnegl %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

OpcodeInstructionClocks DescriptionExample
90nop 3 No operationnop

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

OpcodeInstructionClocks DescriptionExample
F6 /2notb r/m8 2/6 Reverse each bit of r/m bytenotb %dl
notb (%ebx,1)
notb m8(%ebx,1)
notb m8(%ebx,%ebp,1)
F7 /2notw r/m16 2/6 Reverse each bit of r/m wordnotw %cx
notw (%ebx,1)
notw (%ebx,2)
notw (%ebx,%ebp,1)
F7 /2notl r/m32 2/6 Reverse each bit of r/m dwordnotl %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

OpcodeInstructionClocks DescriptionExample
0C iborb imm8,al2 OR immediate byte to ALorb $0x7f,%al
0D iworw imm16,ax2 OR immediate word to AXorw $0x7fff,%ax
0D idorl imm32,eax2 OR immediate dword to EAXorl $0x7fffffff,%eax
80 /1 iborb imm8,r/m82/7 OR immediate byte to r/m byteorb $0x7f,%dl
orb $0x7f,(%ebx,1)
orb $0x7f,m8(%ebx,1)
orb $0x7f,m8(%ebx,%ebp,1)
81 /1 iworw imm16,r/m162/7 OR immediate word to r/m wordorw $0x7fff,%cx
orw $0x7fff,(%ebx,1)
orw $0x7fff,(%ebx,2)
orw $0x7fff,(%ebx,%ebp,1)
81 /1 idorl imm32,r/m322/7 OR immediate dword to r/m dwordorl $0x7fffffff,%ecx
orl $0x7fffffff,(%ebx,2)
orl $0x7fffffff,(%ebx,4)
orl $0x7fffffff,(%ebx,%ebp,1)
83 /1 iborw imm8,r/m162/7 OR sign-extended immediate byte with r/m wordorw $0x7f,%cx
orw $0x7f,(%ebx,1)
orw $0x7f,(%ebx,2)
orw $0x7f,(%ebx,%ebp,1)
83 /1 iborl imm8,r/m322/7 OR sign-extended immediate byte with r/m dwordorl $0x7f,%ecx
orl $0x7f,(%ebx,2)
orl $0x7f,(%ebx,4)
orl $0x7f,(%ebx,%ebp,1)
08 /rorb r8,r/m82/6 OR byte register to r/m byteorb %bh,%dl
orb %bh,(%ebx,1)
orb %bh,m8(%ebx,1)
orb %bh,m8(%ebx,%ebp,1)
09 /rorw r16,r/m162/6 OR word register to r/m wordorw %bx,%cx
orw %bx,(%ebx,1)
orw %bx,(%ebx,2)
orw %bx,(%ebx,%ebp,1)
09 /rorl r32,r/m322/6 OR dword register to r/m dwordorl %ebx,%ecx
orl %ebx,(%ebx,2)
orl %ebx,(%ebx,4)
orl %ebx,(%ebx,%ebp,1)
0A /rorb r/m8,r82/7 OR byte register to r/m byteorb %dl,%bh
orb (%ebx,1),%bh
orb m8(%ebx,1),%bh
orb m8(%ebx,%ebp,1),%bh
0B /rorw r/m16,r162/7 OR word register to r/m wordorw %cx,%bx
orw (%ebx,1),%bx
orw (%ebx,2),%bx
orw (%ebx,%ebp,1),%bx
0B /rorl r/m32,r322/7 OR dword register to r/m dwordorl %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

OpcodeInstructionClocks DescriptionExample
E6 iboutb al,imm810,pm=4*/24** Output byte AL to immediate port numberoutb %al,$0x7f
E7 iboutw ax,imm810,pm=4*/24** Output word AL to immediate port numberoutw %ax,$0x7f
E7 iboutl eax,imm810,pm=4*/24** Output dword AL to immediate port numberoutl %eax,$0x7f
EEoutb al,dx11,pm=5*/25** Output byte AL to port number in outb %al,%dx
EFoutw ax,dx11,pm=5*/25** Output word AL to port number in outw %ax,%dx
EFoutl eax,dx11,pm=5*/25** Output dword AL to port number in DXoutl %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

OpcodeInstructionClocks DescriptionExample
6Eoutsb 14,pm=8*/28** Output byte DS:[(E)SI] to port in DXoutsb
6Foutsw 14,pm=8*/28** Output word DS:[(E)SI] to port in DXoutsw
6Foutsl 14,pm=8*/28** Output dword DS:[(E)SI] to port in DXoutsl

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

OpcodeInstructionClocks DescriptionExample
8F /0popw m165 Pop top of stack into memory wordpopw m16
8F /0popl m325 Pop top of stack into memory dwordpopl m32
58 + rwpopw r164 Pop top of stack into word registerpopw %bx
58 + rdpopl r324 Pop top of stack into dword registerpopl %ebx
1Fpopw ds7,pm=21 Pop top of stack into DSpopw %ds
07popw es7,pm=21 Pop top of stack into ESpopw %es
17popw ss7,pm=21 Pop top of stack into SSpopw %ss
0F A1popw fs7,pm=21 Pop top of stack into FSpopw %fs
0F A9popw gs7,pm=21 Pop top of stack into GSpopw %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

OpcodeInstructionClocks DescriptionExample
61popa 24 Pop DI, SI, BP, SP, BX, DX, CX, and AXpopa
61popal 24 Pop EDI, ESI, EBP, ESP, EDX, ECX, and EAXpopal

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

OpcodeInstructionClocks DescriptionExample
9Dpopf 5 Pop top of stack FLAGSpopf
9Dpopfl 5 Pop top of stack into EFLAGSpopfl

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

OpcodeInstructionClocks DescriptionExample
FF /6pushw m165 Push memory wordpushw m16
FF /6pushl m325 Push memory dwordpushl m32
50 + /rpushw r162 Push register wordpushw %bx
50 + /rpushl r322 Push register dwordpushl %ebx
68pushw imm162 Push immediate wordpushw $0x7fff
68pushl imm322 Push immediate dwordpushl $0x7fffffff
0Epushw cs2 Push CSpushw %cs
16pushw ss2 Push SSpushw %ss
1Epushw ds2 Push DSpushw %ds
06pushw es2 Push ESpushw %es
0F A0pushw fs2 Push FSpushw %fs
OF A8pushw gs2 Push GSpushw %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

OpcodeInstructionClocks DescriptionExample
60pusha 18 Push AX, CX, DX, BX, original SP, BP, SI, and DIpusha
60pushal 18 Push EAX, ECX, EDX, EBX, original ESP, EBP, ESI, and EDIpushal

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

OpcodeInstructionClocks DescriptionExample
9Cpushf 4 Push FLAGSpushf
9Cpushfl 4 Push EFLAGSpushfl

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

OpcodeInstructionClocks DescriptionExample
D0 /2rclb 1,r/m89/10 Rotate 9 bits (CF,r/m byte) left oncerclb $1,%dl
rclb $1,(%ebx,1)
rclb $1,m8(%ebx,1)
rclb $1,m8(%ebx,%ebp,1)
D2 /2rclb cl,r/m89/10 Rotate 9 bits (CF,r/m byte) left CL timesrclb %cl,%dl
rclb %cl,(%ebx,1)
rclb %cl,m8(%ebx,1)
rclb %cl,m8(%ebx,%ebp,1)
C0 /2 ibrclb imm8,r/m89/10 Rotate 9 bits (CF,r/m byte) left imm8 timesrclb $0x7f,%dl
rclb $0x7f,(%ebx,1)
rclb $0x7f,m8(%ebx,1)
rclb $0x7f,m8(%ebx,%ebp,1)
D1 /2rclw 1,r/m169/10 Rotate 17 bits (CF,r/m word) left oncerclw $1,%cx
rclw $1,(%ebx,1)
rclw $1,(%ebx,2)
rclw $1,(%ebx,%ebp,1)
D3 /2rclw cl,r/m169/10 Rotate 17 bits (CF,r/m word) left CL timesrclw %cl,%cx
rclw %cl,(%ebx,1)
rclw %cl,(%ebx,2)
rclw %cl,(%ebx,%ebp,1)
C1 /2 ibrclw imm8,r/m169/10 Rotate 17 bits (CF,r/m word) left imm8 timesrclw $0x7f,%cx
rclw $0x7f,(%ebx,1)
rclw $0x7f,(%ebx,2)
rclw $0x7f,(%ebx,%ebp,1)
D1 /2rcll 1,r/m329/10 Rotate 33 bits (CF,r/m dword) left oncercll $1,%ecx
rcll $1,(%ebx,2)
rcll $1,(%ebx,4)
rcll $1,(%ebx,%ebp,1)
D3 /2rcll cl,r/m329/10 Rotate 33 bits (CF,r/m dword) left CL timesrcll %cl,%ecx
rcll %cl,(%ebx,2)
rcll %cl,(%ebx,4)
rcll %cl,(%ebx,%ebp,1)
C1 /2 ibrcll imm8,r/m329/10 Rotate 33 bits (CF,r/m dword) left imm8 timesrcll $0x7f,%ecx
rcll $0x7f,(%ebx,2)
rcll $0x7f,(%ebx,4)
rcll $0x7f,(%ebx,%ebp,1)
D0 /3rcrb 1,r/m89/10 Rotate 9 bits (CF,r/m byte) right oncercrb $1,%dl
rcrb $1,(%ebx,1)
rcrb $1,m8(%ebx,1)
rcrb $1,m8(%ebx,%ebp,1)
D2 /3rcrb cl,r/m89/10 Rotate 9 bits (CF,r/m byte) right CL timesrcrb %cl,%dl
rcrb %cl,(%ebx,1)
rcrb %cl,m8(%ebx,1)
rcrb %cl,m8(%ebx,%ebp,1)
C0 /3 ibrcrb imm8,r/m89/10 Rotate 9 bits (CF,r/m byte) right imm8 timesrcrb $0x7f,%dl
rcrb $0x7f,(%ebx,1)
rcrb $0x7f,m8(%ebx,1)
rcrb $0x7f,m8(%ebx,%ebp,1)
D1 /3rcrw 1,r/m169/10 Rotate 17 bits (CF,r/m word) right oncercrw $1,%cx
rcrw $1,(%ebx,1)
rcrw $1,(%ebx,2)
rcrw $1,(%ebx,%ebp,1)
D3 /3rcrw cl,r/m169/10 Rotate 17 bits (CF,r/m word) right CL timesrcrw %cl,%cx
rcrw %cl,(%ebx,1)
rcrw %cl,(%ebx,2)
rcrw %cl,(%ebx,%ebp,1)
C1 /3 ibrcrw imm8,r/m169/10 Rotate 17 bits (CF,r/m word) right imm8 timesrcrw $0x7f,%cx
rcrw $0x7f,(%ebx,1)
rcrw $0x7f,(%ebx,2)
rcrw $0x7f,(%ebx,%ebp,1)
D1 /3rcrl 1,r/m329/10 Rotate 33 bits (CF,r/m dword) right oncercrl $1,%ecx
rcrl $1,(%ebx,2)
rcrl $1,(%ebx,4)
rcrl $1,(%ebx,%ebp,1)
D3 /3rcrl cl,r/m329/10 Rotate 33 bits (CF,r/m dword) right CL timesrcrl %cl,%ecx
rcrl %cl,(%ebx,2)
rcrl %cl,(%ebx,4)
rcrl %cl,(%ebx,%ebp,1)
C1 /3 ibrcrl imm8,r/m329/10 Rotate 33 bits (CF,r/m dword) right imm8 timesrcrl $0x7f,%ecx
rcrl $0x7f,(%ebx,2)
rcrl $0x7f,(%ebx,4)
rcrl $0x7f,(%ebx,%ebp,1)
D0 /0rolb 1,r/m83/7 Rotate 8 bits r/m byte left oncerolb $1,%dl
rolb $1,(%ebx,1)
rolb $1,m8(%ebx,1)
rolb $1,m8(%ebx,%ebp,1)
D2 /0rolb cl,r/m83/7 Rotate 8 bits r/m byte left CL timesrolb %cl,%dl
rolb %cl,(%ebx,1)
rolb %cl,m8(%ebx,1)
rolb %cl,m8(%ebx,%ebp,1)
C0 /0 ibrolb imm8,r/m83/7 Rotate 8 bits r/m byte left imm8 timesrolb $0x7f,%dl
rolb $0x7f,(%ebx,1)
rolb $0x7f,m8(%ebx,1)
rolb $0x7f,m8(%ebx,%ebp,1)
D1 /0rolw 1,r/m163/7 Rotate 16 bits r/m word left oncerolw $1,%cx
rolw $1,(%ebx,1)
rolw $1,(%ebx,2)
rolw $1,(%ebx,%ebp,1)
D3 /0rolw cl,r/m163/7 Rotate 16 bits r/m word left CL timesrolw %cl,%cx
rolw %cl,(%ebx,1)
rolw %cl,(%ebx,2)
rolw %cl,(%ebx,%ebp,1)
C1 /0 ibrolw imm8,r/m163/7 Rotate 16 bits r/m word left imm8 timesrolw $0x7f,%cx
rolw $0x7f,(%ebx,1)
rolw $0x7f,(%ebx,2)
rolw $0x7f,(%ebx,%ebp,1)
D1 /0roll 1,r/m323/7 Rotate 32 bits r/m dword left onceroll $1,%ecx
roll $1,(%ebx,2)
roll $1,(%ebx,4)
roll $1,(%ebx,%ebp,1)
D3 /0roll cl,r/m323/7 Rotate 32 bits r/m dword left CL timesroll %cl,%ecx
roll %cl,(%ebx,2)
roll %cl,(%ebx,4)
roll %cl,(%ebx,%ebp,1)
C1 /0 ibroll imm8,r/m323/7 Rotate 32 bits r/m dword left imm8 timesroll $0x7f,%ecx
roll $0x7f,(%ebx,2)
roll $0x7f,(%ebx,4)
roll $0x7f,(%ebx,%ebp,1)
D0 /1rorb 1,r/m83/7 Rotate 8 bits r/m byte right oncerorb $1,%dl
rorb $1,(%ebx,1)
rorb $1,m8(%ebx,1)
rorb $1,m8(%ebx,%ebp,1)
D2 /1rorb cl,r/m83/7 Rotate 8 bits r/m byte right CL timesrorb %cl,%dl
rorb %cl,(%ebx,1)
rorb %cl,m8(%ebx,1)
rorb %cl,m8(%ebx,%ebp,1)
C0 /1 ibrorb imm8,r/m83/7 Rotate 8 bits r/m word right imm8 timesrorb $0x7f,%dl
rorb $0x7f,(%ebx,1)
rorb $0x7f,m8(%ebx,1)
rorb $0x7f,m8(%ebx,%ebp,1)
D1 /1rorw 1,r/m163/7 Rotate 16 bits r/m word right oncerorw $1,%cx
rorw $1,(%ebx,1)
rorw $1,(%ebx,2)
rorw $1,(%ebx,%ebp,1)
D3 /1rorw cl,r/m163/7 Rotate 16 bits r/m word right CL timesrorw %cl,%cx
rorw %cl,(%ebx,1)
rorw %cl,(%ebx,2)
rorw %cl,(%ebx,%ebp,1)
C1 /1 ibrorw imm8,r/m163/7 Rotate 16 bits r/m word right imm8 timesrorw $0x7f,%cx
rorw $0x7f,(%ebx,1)
rorw $0x7f,(%ebx,2)
rorw $0x7f,(%ebx,%ebp,1)
D1 /1rorl 1,r/m323/7 Rotate 32 bits r/m dword right oncerorl $1,%ecx
rorl $1,(%ebx,2)
rorl $1,(%ebx,4)
rorl $1,(%ebx,%ebp,1)
D3 /1rorl cl,r/m323/7 Rotate 32 bits r/m dword right CL timesrorl %cl,%ecx
rorl %cl,(%ebx,2)
rorl %cl,(%ebx,4)
rorl %cl,(%ebx,%ebp,1)
C1 /1 ibrorl imm8,r/m323/7 Rotate 32 bits r/m dword right imm8 timesrorl $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

OpcodeInstructionClocks DescriptionExample
F3 6Crep insb13+6*(E)CX, Input (E)CX bytes from port DX into ES:[(E)DI]rep insb
F3 6Drep insw13+6*(E)CX, Input (E)CX words from port DX into ES:[(E)DI]rep insw
F3 6Drep insl13+6*(E)CX, Input (E)CX dwords from port DX into ES:[(E)DI]rep insl
F3 A4rep movsb5+4*(E)CX Move (E)CX bytes from [(E)SI] to ES:[(E)DI]rep movsb
F3 A5rep movsw5+4*(E)CX Move (E)CX words from [(E)SI] to ES:[(E)DI]rep movsw
F3 A5rep movsl5+4*(E)CX Move (E)CX dwords from [(E)SI] to ES:[(E)DI]rep movsl
F3 AArep stosb5+5*(E)CX Fill (E)CX bytes at ES:[(E)DI] with ALrep stosb
F3 ABrep stosw5+5*(E)CX Fill (E)CX words at ES:[(E)DI] with AXrep stosw
F3 ABrep stosl5+5*(E)CX Fill (E)CX dwords at ES:[(E)DI] with EAXrep stosl
F3 A6repe cmpsb5+9*N Find nonmatching bytes in ES:[(E)DI] and [(E)SI]repe cmpsb
F3 A7repe cmpsw5+9*N Find nonmatching words in ES:[(E)DI] and [(E)SI]repe cmpsw
F3 A7repe cmpsl5+9*N Find nonmatching dwords in ES:[(E)DI] and [(E)SI]repe cmpsl
F3 AErepe scasb5+8*N Find non-AL byte starting at ES:[(E)DI]repe scasb
F3 AFrepe scasw5+8*N Find non-AX word starting at ES:[(E)DI]repe scasw
F3 AFrepe scasl5+8*N Find non-EAX dword starting at ES:[(E)DI]repe scasl
F2 A6repne cmpsb5+9*N Find matching bytes in ES:[(E)DI] and [(E)SI]repne cmpsb
F2 A7repne cmpsw5+9*N Find matching words in ES:[(E)DI] and [(E)SI]repne cmpsw
F2 A7repne cmpsl5+9*N Find matching dwords in ES:[(E)DI] and [(E)SI]repne cmpsl
F2 AErepne scasb5+8*N Find AL, starting at ES:[(E)DI]repne scasb
F2 AFrepne scasw5+8*N Find AX, starting at ES:[(E)DI]repne scasw
F2 AFrepne scasl5+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:

  1. If the address-size attribute is 16 bits, use CX for the count register; if the address-size attribute is 32 bits, use ECX for the count register.
  2. Check CX. If it is zero, exit the iteration, and move to the next instruction.
  3. Acknowledge any pending interrupts.
  4. Perform the string operation once.
  5. Decrement CX or ECX by one; no flags are modified.
  6. Check the zero flag if the string operation is SCAS or CMPS. If the repeat condition does not hold, exit the iteration and move to the next instruction. Exit the iteration if the prefix is REPE and ZF is 0 (the last comparison was not equal), or if the prefix is REPNE and ZF is one (the last comparison was equal).
  7. Return to step 1 for the next iteration.
Repeated CMPS and SCAS instructions can be exited if the count is exhausted or if the zero flag fails the repeat condition. These two cases can be distinguished by using either the JCXZ instruction, or by using the conditional jumps that test the zero flag (JZ, JNZ, and JNE).

Flags Affected

ZF by REP CMPS and REP SCAS as described above

Protected Mode Exceptions

#UD if a repeat prefix is used before an instruction that is not in the list above; further exceptions can be generated when the string operation is executed; refer to the descriptions of the string instructions themselves

Real Address Mode Exceptions

Interrupt 6 if a repeat prefix is used before an instruction that is not in the list above; further exceptions can be generated when the string operation is executed; refer to the descriptions of the string instructions themselves

Virtual 8086 Mode Exceptions

#UD if a repeat prefix is used before an instruction that is not in the list above; further exceptions can be generated when the string operation is executed; refer to the descriptions of the string instructions themselves

Notes

Not all input/output ports can handle the rate at which the REP INS and REP OUTS instructions execute.


RET -- Return from Procedure

OpcodeInstructionClocks DescriptionExample
C3ret 10+m Return (near) to callerret
CBret 18+m,pm=32+m Return (far) to caller, same privilegeret
CBret pm=68 Return (far), lesser privilege, switch stacksret
C2 iwretw imm1610+m Return (near), pop imm16 bytes of parametersretw $0x7fff
CA iwretw imm1618+m,pm=32+m Return (far), same privilege, pop imm16 bytesretw $0x7fff
CA iwretw imm16pm=68 Return (far), lesser privilege, pop imm16 bytesretw $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

OpcodeInstructionClocks DescriptionExample
9Esahf 3 Store AH into flags SF ZF xx AF xx PF xx CFsahf

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

OpcodeInstructionClocks DescriptionExample
D0 /4salb 1,r/m83/7 Multiply r/m byte by 2, oncesalb $1,%dl
salb $1,(%ebx,1)
salb $1,m8(%ebx,1)
salb $1,m8(%ebx,%ebp,1)
D2 /4salb cl,r/m83/7 Multiply r/m byte by 2, CL timessalb %cl,%dl
salb %cl,(%ebx,1)
salb %cl,m8(%ebx,1)
salb %cl,m8(%ebx,%ebp,1)
C0 /4 ibsalb imm8,r/m83/7 Multiply r/m byte by 2, imm8 timessalb $0x7f,%dl
salb $0x7f,(%ebx,1)
salb $0x7f,m8(%ebx,1)
salb $0x7f,m8(%ebx,%ebp,1)
D1 /4salw 1,r/m163/7 Multiply r/m word by 2, oncesalw $1,%cx
salw $1,(%ebx,1)
salw $1,(%ebx,2)
salw $1,(%ebx,%ebp,1)
D3 /4salw cl,r/m163/7 Multiply r/m word by 2, CL timessalw %cl,%cx
salw %cl,(%ebx,1)
salw %cl,(%ebx,2)
salw %cl,(%ebx,%ebp,1)
C1 /4 ibsalw imm8,r/m163/7 Multiply r/m word by 2, imm8 timessalw $0x7f,%cx
salw $0x7f,(%ebx,1)
salw $0x7f,(%ebx,2)
salw $0x7f,(%ebx,%ebp,1)
D1 /4sall 1,r/m323/7 Multiply r/m dword by 2, oncesall $1,%ecx
sall $1,(%ebx,2)
sall $1,(%ebx,4)
sall $1,(%ebx,%ebp,1)
D3 /4sall cl,r/m323/7 Multiply r/m dword by 2, CL timessall %cl,%ecx
sall %cl,(%ebx,2)
sall %cl,(%ebx,4)
sall %cl,(%ebx,%ebp,1)
C1 /4 ibsall imm8,r/m323/7 Multiply r/m dword by 2, imm8 timessall $0x7f,%ecx
sall $0x7f,(%ebx,2)
sall $0x7f,(%ebx,4)
sall $0x7f,(%ebx,%ebp,1)
D0 /7sarb 1,r/m83/7 Signed divide^(1) r/m byte by 2, oncesarb $1,%dl
sarb $1,(%ebx,1)
sarb $1,m8(%ebx,1)
sarb $1,m8(%ebx,%ebp,1)
D2 /7sarb cl,r/m83/7 Signed divide^(1) r/m byte by 2, CL timessarb %cl,%dl
sarb %cl,(%ebx,1)
sarb %cl,m8(%ebx,1)
sarb %cl,m8(%ebx,%ebp,1)
C0 /7 ibsarb imm8,r/m83/7 Signed divide^(1) r/m byte by 2, imm8 timessarb $0x7f,%dl
sarb $0x7f,(%ebx,1)
sarb $0x7f,m8(%ebx,1)
sarb $0x7f,m8(%ebx,%ebp,1)
D1 /7sarw 1,r/m163/7 Signed divide^(1) r/m word by 2, oncesarw $1,%cx
sarw $1,(%ebx,1)
sarw $1,(%ebx,2)
sarw $1,(%ebx,%ebp,1)
D3 /7sarw cl,r/m163/7 Signed divide^(1) r/m word by 2, CL timessarw %cl,%cx
sarw %cl,(%ebx,1)
sarw %cl,(%ebx,2)
sarw %cl,(%ebx,%ebp,1)
C1 /7 ibsarw imm8,r/m163/7 Signed divide^(1) r/m word by 2, imm8 timessarw $0x7f,%cx
sarw $0x7f,(%ebx,1)
sarw $0x7f,(%ebx,2)
sarw $0x7f,(%ebx,%ebp,1)
D1 /7sarl 1,r/m323/7 Signed divide^(1) r/m dword by 2, oncesarl $1,%ecx
sarl $1,(%ebx,2)
sarl $1,(%ebx,4)
sarl $1,(%ebx,%ebp,1)
D3 /7sarl cl,r/m323/7 Signed divide^(1) r/m dword by 2, CL timessarl %cl,%ecx
sarl %cl,(%ebx,2)
sarl %cl,(%ebx,4)
sarl %cl,(%ebx,%ebp,1)
C1 /7 ibsarl imm8,r/m323/7 Signed divide^(1) r/m dword by 2, imm8 timessarl $0x7f,%ecx
sarl $0x7f,(%ebx,2)
sarl $0x7f,(%ebx,4)
sarl $0x7f,(%ebx,%ebp,1)
D0 /4shlb 1,r/m83/7 Multiply r/m byte by 2, onceshlb $1,%dl
shlb $1,(%ebx,1)
shlb $1,m8(%ebx,1)
shlb $1,m8(%ebx,%ebp,1)
D2 /4shlb cl,r/m83/7 Multiply r/m byte by 2, CL timesshlb %cl,%dl
shlb %cl,(%ebx,1)
shlb %cl,m8(%ebx,1)
shlb %cl,m8(%ebx,%ebp,1)
C0 /4 ibshlb imm8,r/m83/7 Multiply r/m byte by 2, imm8 timesshlb $0x7f,%dl
shlb $0x7f,(%ebx,1)
shlb $0x7f,m8(%ebx,1)
shlb $0x7f,m8(%ebx,%ebp,1)
D1 /4shlw 1,r/m163/7 Multiply r/m word by 2, onceshlw $1,%cx
shlw $1,(%ebx,1)
shlw $1,(%ebx,2)
shlw $1,(%ebx,%ebp,1)
D3 /4shlw cl,r/m163/7 Multiply r/m word by 2, CL timesshlw %cl,%cx
shlw %cl,(%ebx,1)
shlw %cl,(%ebx,2)
shlw %cl,(%ebx,%ebp,1)
C1 /4 ibshlw imm8,r/m163/7 Multiply r/m word by 2, imm8 timesshlw $0x7f,%cx
shlw $0x7f,(%ebx,1)
shlw $0x7f,(%ebx,2)
shlw $0x7f,(%ebx,%ebp,1)
D1 /4shll 1,r/m323/7 Multiply r/m dword by 2, onceshll $1,%ecx
shll $1,(%ebx,2)
shll $1,(%ebx,4)
shll $1,(%ebx,%ebp,1)
D3 /4shll cl,r/m323/7 Multiply r/m dword by 2, CL timesshll %cl,%ecx
shll %cl,(%ebx,2)
shll %cl,(%ebx,4)
shll %cl,(%ebx,%ebp,1)
C1 /4 ibshll imm8,r/m323/7 Multiply r/m dword by 2, imm8 timesshll $0x7f,%ecx
shll $0x7f,(%ebx,2)
shll $0x7f,(%ebx,4)
shll $0x7f,(%ebx,%ebp,1)
D0 /5shrb 1,r/m83/7 Unsigned divide r/m byte by 2, onceshrb $1,%dl
shrb $1,(%ebx,1)
shrb $1,m8(%ebx,1)
shrb $1,m8(%ebx,%ebp,1)
D2 /5shrb cl,r/m83/7 Unsigned divide r/m byte by 2, CL timesshrb %cl,%dl
shrb %cl,(%ebx,1)
shrb %cl,m8(%ebx,1)
shrb %cl,m8(%ebx,%ebp,1)
C0 /5 ibshrb imm8,r/m83/7 Unsigned divide r/m byte by 2, imm8 timesshrb $0x7f,%dl
shrb $0x7f,(%ebx,1)
shrb $0x7f,m8(%ebx,1)
shrb $0x7f,m8(%ebx,%ebp,1)
D1 /5shrw 1,r/m163/7 Unsigned divide r/m word by 2, onceshrw $1,%cx
shrw $1,(%ebx,1)
shrw $1,(%ebx,2)
shrw $1,(%ebx,%ebp,1)
D3 /5shrw cl,r/m163/7 Unsigned divide r/m word by 2, CL timesshrw %cl,%cx
shrw %cl,(%ebx,1)
shrw %cl,(%ebx,2)
shrw %cl,(%ebx,%ebp,1)
C1 /5 ibshrw imm8,r/m163/7 Unsigned divide r/m word by 2, imm8 timesshrw $0x7f,%cx
shrw $0x7f,(%ebx,1)
shrw $0x7f,(%ebx,2)
shrw $0x7f,(%ebx,%ebp,1)
D1 /5shrl 1,r/m323/7 Unsigned divide r/m dword by 2, onceshrl $1,%ecx
shrl $1,(%ebx,2)
shrl $1,(%ebx,4)
shrl $1,(%ebx,%ebp,1)
D3 /5shrl cl,r/m323/7 Unsigned divide r/m dword by 2, CL timesshrl %cl,%ecx
shrl %cl,(%ebx,2)
shrl %cl,(%ebx,4)
shrl %cl,(%ebx,%ebp,1)
C1 /5 ibshrl imm8,r/m323/7 Unsigned divide r/m dword by 2, imm8 timesshrl $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

OpcodeInstructionClocks DescriptionExample
1C ibsbbb imm8,al2 Subtract with borrow immediate byte from ALsbbb $0x7f,%al
1D iwsbbw imm16,ax2 Subtract with borrow immediate word from AXsbbw $0x7fff,%ax
1D idsbbl imm32,eax2 Subtract with borrow immediate dword from EAXsbbl $0x7fffffff,%eax
80 /3 ibsbbb imm8,r/m82/7 Subtract with borrow immediate byte from r/m bytesbbb $0x7f,%dl
sbbb $0x7f,(%ebx,1)
sbbb $0x7f,m8(%ebx,1)
sbbb $0x7f,m8(%ebx,%ebp,1)
81 /3 iwsbbw imm16,r/m162/7 Subtract with borrow immediate word from r/m wordsbbw $0x7fff,%cx
sbbw $0x7fff,(%ebx,1)
sbbw $0x7fff,(%ebx,2)
sbbw $0x7fff,(%ebx,%ebp,1)
81 /3 idsbbl imm32,r/m322/7 Subtract with borrow immediate dword from r/m dwordsbbl $0x7fffffff,%ecx
sbbl $0x7fffffff,(%ebx,2)
sbbl $0x7fffffff,(%ebx,4)
sbbl $0x7fffffff,(%ebx,%ebp,1)
83 /3 ibsbbw imm8,r/m162/7 Subtract with borrow sign-extended immediate byte from r/m wordsbbw $0x7f,%cx
sbbw $0x7f,(%ebx,1)
sbbw $0x7f,(%ebx,2)
sbbw $0x7f,(%ebx,%ebp,1)
83 /3 ibsbbl imm8,r/m322/7 Subtract with borrow sign-extended immediate byte from r/m dwordsbbl $0x7f,%ecx
sbbl $0x7f,(%ebx,2)
sbbl $0x7f,(%ebx,4)
sbbl $0x7f,(%ebx,%ebp,1)
18 /rsbbb r8,r/m82/6 Subtract with borrow byte register from r/m bytesbbb %bh,%dl
sbbb %bh,(%ebx,1)
sbbb %bh,m8(%ebx,1)
sbbb %bh,m8(%ebx,%ebp,1)
19 /rsbbw r16,r/m162/6 Subtract with borrow word register from r/m wordsbbw %bx,%cx
sbbw %bx,(%ebx,1)
sbbw %bx,(%ebx,2)
sbbw %bx,(%ebx,%ebp,1)
19 /rsbbl r32,r/m322/6 Subtract with borrow dword register from r/m dwordsbbl %ebx,%ecx
sbbl %ebx,(%ebx,2)
sbbl %ebx,(%ebx,4)
sbbl %ebx,(%ebx,%ebp,1)
1A /rsbbb r/m8,r82/7 Subtract with borrow byte register from r/m bytesbbb %dl,%bh
sbbb (%ebx,1),%bh
sbbb m8(%ebx,1),%bh
sbbb m8(%ebx,%ebp,1),%bh
1B /rsbbw r/m16,r162/7 Subtract with borrow word register from r/m wordsbbw %cx,%bx
sbbw (%ebx,1),%bx
sbbw (%ebx,2),%bx
sbbw (%ebx,%ebp,1),%bx
1B /rsbbl r/m32,r322/7 Subtract with borrow dword register from r/m dwordsbbl %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

OpcodeInstructionClocks DescriptionExample
AEscasb 7 Compare bytes AL-ES:[DI], update (E)DIscasb
AFscasw 7 Compare words AX-ES:[DI], update (E)DIscasw
AFscasl 7 Compare dwords EAX-ES:[DI], update (E)DIscasl

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

OpcodeInstructionClocks DescriptionExample
0F 97setab r/m84/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 93setaeb r/m84/5 Set byte if above or equal (CF=0)setaeb %dl
setaeb (%ebx,1)
setaeb m8(%ebx,1)
setaeb m8(%ebx,%ebp,1)
0F 92setbb r/m84/5 Set byte if below (CF=1)setbb %dl
setbb (%ebx,1)
setbb m8(%ebx,1)
setbb m8(%ebx,%ebp,1)
0F 96setbeb r/m84/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 92setcb r/m84/5 Set if carry (CF=1)setcb %dl
setcb (%ebx,1)
setcb m8(%ebx,1)
setcb m8(%ebx,%ebp,1)
0F 94seteb r/m84/5 Set byte if equal (ZF=1)seteb %dl
seteb (%ebx,1)
seteb m8(%ebx,1)
seteb m8(%ebx,%ebp,1)
0F 9Fsetgb r/m84/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 9Dsetgeb r/m84/5 Set byte if greater or equal (SF=OF)setgeb %dl
setgeb (%ebx,1)
setgeb m8(%ebx,1)
setgeb m8(%ebx,%ebp,1)
0F 9Csetlb r/m84/5 Set byte if less (SF<setlb %dl
setlb (%ebx,1)
setlb m8(%ebx,1)
setlb m8(%ebx,%ebp,1)
0F 9Esetleb r/m84/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 96setnab r/m84/5 Set byte if not above (CF=1)setnab %dl
setnab (%ebx,1)
setnab m8(%ebx,1)
setnab m8(%ebx,%ebp,1)
0F 92setnaeb r/m84/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 93setnbb r/m84/5 Set byte if not below (CF=0)setnbb %dl
setnbb (%ebx,1)
setnbb m8(%ebx,1)
setnbb m8(%ebx,%ebp,1)
0F 97setnbeb r/m84/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 93setncb r/m84/5 Set byte if not carry (CF=0)setncb %dl
setncb (%ebx,1)
setncb m8(%ebx,1)
setncb m8(%ebx,%ebp,1)
0F 95setneb r/m84/5 Set byte if not equal (ZF=0)setneb %dl
setneb (%ebx,1)
setneb m8(%ebx,1)
setneb m8(%ebx,%ebp,1)
0F 9Esetngb r/m84/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 9Csetngeb r/m84/5 Set if not greater or equal (SF<setngeb %dl
setngeb (%ebx,1)
setngeb m8(%ebx,1)
setngeb m8(%ebx,%ebp,1)
0F 9Dsetnlb r/m84/5 Set byte if not less (SF=OF)setnlb %dl
setnlb (%ebx,1)
setnlb m8(%ebx,1)
setnlb m8(%ebx,%ebp,1)
0F 9Fsetnleb r/m84/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 91setnob r/m84/5 Set byte if not overflow (OF=0)setnob %dl
setnob (%ebx,1)
setnob m8(%ebx,1)
setnob m8(%ebx,%ebp,1)
0F 9Bsetnpb r/m84/5 Set byte if not parity (PF=0)setnpb %dl
setnpb (%ebx,1)
setnpb m8(%ebx,1)
setnpb m8(%ebx,%ebp,1)
0F 99setnsb r/m84/5 Set byte if not sign (SF=0)setnsb %dl
setnsb (%ebx,1)
setnsb m8(%ebx,1)
setnsb m8(%ebx,%ebp,1)
0F 95setnzb r/m84/5 Set byte if not zero (ZF=0)setnzb %dl
setnzb (%ebx,1)
setnzb m8(%ebx,1)
setnzb m8(%ebx,%ebp,1)
0F 90setob r/m84/5 Set byte if overflow (OF=1)setob %dl
setob (%ebx,1)
setob m8(%ebx,1)
setob m8(%ebx,%ebp,1)
0F 9Asetpb r/m84/5 Set byte if parity (PF=1)setpb %dl
setpb (%ebx,1)
setpb m8(%ebx,1)
setpb m8(%ebx,%ebp,1)
0F 9Asetpeb r/m84/5 Set byte if parity even (PF=1)setpeb %dl
setpeb (%ebx,1)
setpeb m8(%ebx,1)
setpeb m8(%ebx,%ebp,1)
0F 9Bsetpob r/m84/5 Set byte if parity odd (PF=0)setpob %dl
setpob (%ebx,1)
setpob m8(%ebx,1)
setpob m8(%ebx,%ebp,1)
0F 98setsb r/m84/5 Set byte if sign (SF=1)setsb %dl
setsb (%ebx,1)
setsb m8(%ebx,1)
setsb m8(%ebx,%ebp,1)
0F 94setzb r/m84/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

OpcodeInstructionClocks DescriptionExample
0F 01 /0sgdt m9 Store GDTR to msgdt m
0F 01 /1sidt m9 Store IDTR to msidt 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

OpcodeInstructionClocks DescriptionExample
0F A4shldw r16,r/m163/7 r/m16 gets SHL of r/m16 concatenated with r16shldw %bx,%cx
shldw %bx,(%ebx,1)
shldw %bx,(%ebx,2)
shldw %bx,(%ebx,%ebp,1)
0F A4shldl r32,r/m323/7 r/m32 gets SHL of r/m32 concatenated with r32shldl %ebx,%ecx
shldl %ebx,(%ebx,2)
shldl %ebx,(%ebx,4)
shldl %ebx,(%ebx,%ebp,1)
0F A5shldw r16,r/m163/7 r/m16 gets SHL of r/m16 concatenated with r16shldw %bx,%cx
shldw %bx,(%ebx,1)
shldw %bx,(%ebx,2)
shldw %bx,(%ebx,%ebp,1)
0F A5shldl r32,r/m323/7 r/m32 gets SHL of r/m32 concatenated with r32shldl %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

OpcodeInstructionClocks DescriptionExample
0F ACshrdw r16,r/m163/7 r/m16 gets SHR of r/m16 concatenated with r16shrdw %bx,%cx
shrdw %bx,(%ebx,1)
shrdw %bx,(%ebx,2)
shrdw %bx,(%ebx,%ebp,1)
0F ACshrdl r32,r/m323/7 r/m32 gets SHR of r/m32 concatenated with r32shrdl %ebx,%ecx
shrdl %ebx,(%ebx,2)
shrdl %ebx,(%ebx,4)
shrdl %ebx,(%ebx,%ebp,1)
0F ADshrdw r16,r/m163/7 r/m16 gets SHR of r/m16 concatenated with r16shrdw %bx,%cx
shrdw %bx,(%ebx,1)
shrdw %bx,(%ebx,2)
shrdw %bx,(%ebx,%ebp,1)
0F ADshrdl r32,r/m323/7 r/m32 gets SHR of r/m32 concatenated with r32shrdl %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

OpcodeInstructionClocks DescriptionExample
0F 00 /0sldtw r/m16pm=2/2 Store LDTR to EA wordsldtw %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

OpcodeInstructionClocks DescriptionExample
0F 01 /4smsww r/m162/3,pm=2/2 Store machine status word to EA wordsmsww %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

OpcodeInstructionClocks DescriptionExample
F9stc 2 Set carry flagstc

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

OpcodeInstructionClocks DescriptionExample
FDstd 2 Set direction flag so (E)SI and/or (E)DI decrementstd

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

OpcodeInstructionClocks DescriptionExample
F13sti 3 Set interrupt flagsti

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

OpcodeInstructionClocks DescriptionExample
AAstosb 4 Store AL in byte ES:[(E)DI], update (E)DIstosb
ABstosw 4 Store AX in word ES:[(E)DI], update (E)DIstosw
ABstosl 4 Store EAX in dword ES:[(E)DI], update (E)DIstosl

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

OpcodeInstructionClocks DescriptionExample
0F 00 /1strw r/m16pm=23/27 Load EA word into task registerstrw %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

OpcodeInstructionClocks DescriptionExample
2C ibsubb imm8,al2 Subtract immediate byte from ALsubb $0x7f,%al
2D iwsubw imm16,ax2 Subtract immediate word from AXsubw $0x7fff,%ax
2D idsubl imm32,eax2 Subtract immediate dword from EAXsubl $0x7fffffff,%eax
80 /5 ibsubb imm8,r/m82/7 Subtract immediate byte from r/m bytesubb $0x7f,%dl
subb $0x7f,(%ebx,1)
subb $0x7f,m8(%ebx,1)
subb $0x7f,m8(%ebx,%ebp,1)
81 /5 iwsubw imm16,r/m162/7 Subtract immediate word from r/m wordsubw $0x7fff,%cx
subw $0x7fff,(%ebx,1)
subw $0x7fff,(%ebx,2)
subw $0x7fff,(%ebx,%ebp,1)
81 /5 idsubl imm32,r/m322/7 Subtract immediate dword from r/m dwordsubl $0x7fffffff,%ecx
subl $0x7fffffff,(%ebx,2)
subl $0x7fffffff,(%ebx,4)
subl $0x7fffffff,(%ebx,%ebp,1)
83 /5 ibsubw imm8,r/m162/7 Subtract sign-extended immediate byte from r/m wordsubw $0x7f,%cx
subw $0x7f,(%ebx,1)
subw $0x7f,(%ebx,2)
subw $0x7f,(%ebx,%ebp,1)
83 /5 ibsubl imm8,r/m322/7 Subtract sign-extended immediate byte from r/m dwordsubl $0x7f,%ecx
subl $0x7f,(%ebx,2)
subl $0x7f,(%ebx,4)
subl $0x7f,(%ebx,%ebp,1)
28 /rsubb r8,r/m82/6 Subtract byte register from r/m bytesubb %bh,%dl
subb %bh,(%ebx,1)
subb %bh,m8(%ebx,1)
subb %bh,m8(%ebx,%ebp,1)
29 /rsubw r16,r/m162/6 Subtract word register from r/m wordsubw %bx,%cx
subw %bx,(%ebx,1)
subw %bx,(%ebx,2)
subw %bx,(%ebx,%ebp,1)
29 /rsubl r32,r/m322/6 Subtract dword register from r/m dwordsubl %ebx,%ecx
subl %ebx,(%ebx,2)
subl %ebx,(%ebx,4)
subl %ebx,(%ebx,%ebp,1)
2A /rsubb r/m8,r82/7 Subtract byte register from r/m bytesubb %dl,%bh
subb (%ebx,1),%bh
subb m8(%ebx,1),%bh
subb m8(%ebx,%ebp,1),%bh
2B /rsubw r/m16,r162/7 Subtract word register from r/m wordsubw %cx,%bx
subw (%ebx,1),%bx
subw (%ebx,2),%bx
subw (%ebx,%ebp,1),%bx
2B /rsubl r/m32,r322/7 Subtract dword register from r/m dwordsubl %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

OpcodeInstructionClocks DescriptionExample
A8 ibtestb imm8,al2 AND immediate byte with ALtestb $0x7f,%al
A9 iwtestw imm16,ax2 AND immediate word with AXtestw $0x7fff,%ax
A9 idtestl imm32,eax2 AND immediate dword with EAXtestl $0x7fffffff,%eax
F6 /0 ibtestb imm8,r/m82/5 AND immediate byte with r/m bytetestb $0x7f,%dl
testb $0x7f,(%ebx,1)
testb $0x7f,m8(%ebx,1)
testb $0x7f,m8(%ebx,%ebp,1)
F7 /0 iwtestw imm16,r/m162/5 AND immediate word with r/m wordtestw $0x7fff,%cx
testw $0x7fff,(%ebx,1)
testw $0x7fff,(%ebx,2)
testw $0x7fff,(%ebx,%ebp,1)
F7 /0 idtestl imm32,r/m322/5 AND immediate dword with r/m dwordtestl $0x7fffffff,%ecx
testl $0x7fffffff,(%ebx,2)
testl $0x7fffffff,(%ebx,4)
testl $0x7fffffff,(%ebx,%ebp,1)
84 /rtestb r8,r/m82/5 AND byte register with r/m bytetestb %bh,%dl
testb %bh,(%ebx,1)
testb %bh,m8(%ebx,1)
testb %bh,m8(%ebx,%ebp,1)
85 /rtestw r16,r/m162/5 AND word register with r/m wordtestw %bx,%cx
testw %bx,(%ebx,1)
testw %bx,(%ebx,2)
testw %bx,(%ebx,%ebp,1)
85 /rtestl r32,r/m322/5 AND dword register with r/m dwordtestl %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

OpcodeInstructionClocks DescriptionExample
0F 00 /4verrw r/m16pm=10/11 Set ZF=1 if segment can be read, selector in r/m16verrw %cx
verrw (%ebx,1)
verrw (%ebx,2)
verrw (%ebx,%ebp,1)
0F 00 /5verww r/m16pm=15/16 Set ZF=1 if segment can be written, selector in r/m16verww %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)

OpcodeInstructionClocks DescriptionExample
9Bwait 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

OpcodeInstructionClocks DescriptionExample
90 + rxchgw r16,ax3 Exchange word register with AXxchgw %bx,%ax
90 + rxchgw ax,r163 Exchange word register with AXxchgw %ax,%bx
90 + rxchgl r32,eax3 Exchange dword register with EAXxchgl %ebx,%eax
90 + rxchgl eax,r323 Exchange dword register with EAXxchgl %eax,%ebx
86 /rxchgb r8,r/m83 Exchange byte register with EA bytexchgb %bh,%dl
xchgb %bh,(%ebx,1)
xchgb %bh,m8(%ebx,1)
xchgb %bh,m8(%ebx,%ebp,1)
86 /rxchgb r/m8,r83/5 Exchange byte register with EA bytexchgb %dl,%bh
xchgb (%ebx,1),%bh
xchgb m8(%ebx,1),%bh
xchgb m8(%ebx,%ebp,1),%bh
87 /rxchgw r16,r/m163 Exchange word register with EA wordxchgw %bx,%cx
xchgw %bx,(%ebx,1)
xchgw %bx,(%ebx,2)
xchgw %bx,(%ebx,%ebp,1)
87 /rxchgw r/m16,r163/5 Exchange word register with EA wordxchgw %cx,%bx
xchgw (%ebx,1),%bx
xchgw (%ebx,2),%bx
xchgw (%ebx,%ebp,1),%bx
87 /rxchgl r32,r/m323 Exchange dword register with EA dwordxchgl %ebx,%ecx
xchgl %ebx,(%ebx,2)
xchgl %ebx,(%ebx,4)
xchgl %ebx,(%ebx,%ebp,1)
87 /rxchgl r/m32,r323/5 Exchange dword register with EA dwordxchgl %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

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

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

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