<html>
<head>
<title>
17.3.S 'S' Instructions
</title>
<body>
<pre>
<a name="17-03-S"></a>
Prev: <a href="chp17-r3.htm">17.3.R 'R' Instructions </a>
Next: <a href="chp17-t3.htm">17.3.T 'T' Instructions </a>
<hr>
<h2>
17.3.S 'S' Instructions
</h2>
<a name="17-03-SAHF"></a>
<h3>SAHF -- Store AH into Flags</h3>
Opcode Instruction Clocks Description
9E SAHF 3 Store AH into flags SF ZF xx AF xx PF xx CF
Operation
SF:ZF:xx:AF:xx:PF:xx:CF <- AH;
<b>Description</b>
SAHF loads the flags listed above with values from the AH register,
from bits 7, 6, 4, 2, and 0, respectively.
<b>Flags Affected</b>
SF, ZF, AF, PF, and CF as described above
<b>Protected Mode Exceptions</b>
None
<b>Real Address Mode Exceptions</b>
None
<b>Virtual 8086 Mode Exceptions</b>
None
<a name="17-03-SAL"></a>
<h3>SAL/SAR/SHL/SHR -- Shift Instructions</h3>
Opcode Instruction Clocks Description
D0 /4 SAL r/m8,1 3/7 Multiply r/m byte by 2, once
D2 /4 SAL r/m8,CL 3/7 Multiply r/m byte by 2, CL times
C0 /4 ib SAL r/m8,imm8 3/7 Multiply r/m byte by 2, imm8
times
D1 /4 SAL r/m16,1 3/7 Multiply r/m word by 2, once
D3 /4 SAL r/m16,CL 3/7 Multiply r/m word by 2, CL times
C1 /4 ib SAL r/m16,imm8 3/7 Multiply r/m word by 2, imm8
times
D1 /4 SAL r/m32,1 3/7 Multiply r/m dword by 2, once
D3 /4 SAL r/m32,CL 3/7 Multiply r/m dword by 2, CL
times
C1 /4 ib SAL r/m32,imm8 3/7 Multiply r/m dword by 2, imm8
times
D0 /7 SAR r/m8,1 3/7 Signed divide^(1) r/m byte by 2,
once
D2 /7 SAR r/m8,CL 3/7 Signed divide^(1) r/m byte by 2,
CL times
C0 /7 ib SAR r/m8,imm8 3/7 Signed divide^(1) r/m byte by 2,
imm8 times
D1 /7 SAR r/m16,1 3/7 Signed divide^(1) r/m word by 2,
once
D3 /7 SAR r/m16,CL 3/7 Signed divide^(1) r/m word by 2,
CL times
C1 /7 ib SAR r/m16,imm8 3/7 Signed divide^(1) r/m word by 2,
imm8 times
D1 /7 SAR r/m32,1 3/7 Signed divide^(1) r/m dword by 2,
once
D3 /7 SAR r/m32,CL 3/7 Signed divide^(1) r/m dword by 2,
CL times
C1 /7 ib SAR r/m32,imm8 3/7 Signed divide^(1) r/m dword by 2,
imm8 times
D0 /4 SHL r/m8,1 3/7 Multiply r/m byte by 2, once
D2 /4 SHL r/m8,CL 3/7 Multiply r/m byte by 2, CL times
C0 /4 ib SHL r/m8,imm8 3/7 Multiply r/m byte by 2, imm8
times
D1 /4 SHL r/m16,1 3/7 Multiply r/m word by 2, once
D3 /4 SHL r/m16,CL 3/7 Multiply r/m word by 2, CL times
C1 /4 ib SHL r/m16,imm8 3/7 Multiply r/m word by 2, imm8
times
D1 /4 SHL r/m32,1 3/7 Multiply r/m dword by 2, once
D3 /4 SHL r/m32,CL 3/7 Multiply r/m dword by 2, CL
times
C1 /4 ib SHL r/m32,imm8 3/7 Multiply r/m dword by 2, imm8
times
D0 /5 SHR r/m8,1 3/7 Unsigned divide r/m byte by 2,
once
D2 /5 SHR r/m8,CL 3/7 Unsigned divide r/m byte by 2,
CL times
C0 /5 ib SHR r/m8,imm8 3/7 Unsigned divide r/m byte by 2,
imm8 times
D1 /5 SHR r/m16,1 3/7 Unsigned divide r/m word by 2,
once
D3 /5 SHR r/m16,CL 3/7 Unsigned divide r/m word by 2,
CL times
C1 /5 ib SHR r/m16,imm8 3/7 Unsigned divide r/m word by 2,
imm8 times
D1 /5 SHR r/m32,1 3/7 Unsigned divide r/m dword by 2,
once
D3 /5 SHR r/m32,CL 3/7 Unsigned divide r/m dword by 2,
CL times
C1 /5 ib SHR r/m32,imm8 3/7 Unsigned divide r/m dword by 2,
imm8 times
Not the same division as IDIV; rounding is toward negative infinity.
Operation
(* COUNT is the second parameter *)
(temp) <- COUNT;
WHILE (temp <> 0)
DO
IF instruction is SAL or SHL
THEN CF <- high-order bit of r/m;
FI;
IF instruction is SAR or SHR
THEN CF <- low-order bit of r/m;
FI;
IF instruction = SAL or SHL
THEN r/m <- r/m * 2;
FI;
IF instruction = SAR
THEN r/m <- r/m /2 (*Signed divide, rounding toward negative infinity*);
FI;
IF instruction = SHR
THEN r/m <- r/m / 2; (* Unsigned divide *);
FI;
temp <- temp - 1;
OD;
(* Determine overflow for the various instructions *)
IF COUNT = 1
THEN
IF instruction is SAL or SHL
THEN OF <- high-order bit of r/m <> (CF);
FI;
IF instruction is SAR
THEN OF <- 0;
FI;
IF instruction is SHR
THEN OF <- high-order bit of operand;
FI;
ELSE OF <- undefined;
FI;
<b>Description</b>
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.
<b>Flags Affected</b>
OF for single shifts; OF is undefined for multiple shifts; CF, ZF, PF,
and SF as described in Appendix C
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
<b>Virtual 8086 Mode Exceptions</b>
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
<a name="17-03-SBB"></a>
<h3>SBB -- Integer Subtraction with Borrow</h3>
Opcode Instruction Clocks Description
1C ib SBB AL,imm8 2 Subtract with borrow immediate byte
from AL
1D iw SBB AX,imm16 2 Subtract with borrow immediate word
from AX
1D id SBB EAX,imm32 2 Subtract with borrow immediate
dword from EAX
80 /3 ib SBB r/m8,imm8 2/7 Subtract with borrow immediate byte
from r/m byte
81 /3 iw SBB r/m16,imm16 2/7 Subtract with borrow immediate word
from r/m word
81 /3 id SBB r/m32,imm32 2/7 Subtract with borrow immediate
dword from r/m dword
83 /3 ib SBB r/m16,imm8 2/7 Subtract with borrow sign-extended
immediate byte from r/m word
83 /3 ib SBB r/m32,imm8 2/7 Subtract with borrow sign-extended
immediate byte from r/m dword
18 /r SBB r/m8,r8 2/6 Subtract with borrow byte register
from r/m byte
19 /r SBB r/m16,r16 2/6 Subtract with borrow word register
from r/m word
19 /r SBB r/m32,r32 2/6 Subtract with borrow dword register
from r/m dword
1A /r SBB r8,r/m8 2/7 Subtract with borrow byte register
from r/m byte
1B /r SBB r16,r/m16 2/7 Subtract with borrow word register
from r/m word
1B /r SBB r32,r/m32 2/7 Subtract with borrow dword register
from r/m dword
Operation
IF SRC is a byte and DEST is a word or dword
THEN DEST = DEST - (SignExtend(SRC) + CF)
ELSE DEST <- DEST - (SRC + CF);
<b>Description</b>
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.
<b>Flags Affected</b>
OF, SF, ZF, AF, PF, and CF as described in Appendix C
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
<b>Virtual 8086 Mode Exceptions</b>
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
<a name="17-03-SCAS"></a>
<h3>SCAS/SCASB/SCASW/SCASD -- Compare String Data</h3>
Opcode Instruction Clocks Description
AE SCAS m8 7 Compare bytes AL-ES:[DI], update (E)DI
AF SCAS m16 7 Compare words AX-ES:[DI], update (E)DI
AF SCAS m32 7 Compare dwords EAX-ES:[DI], update (E)DI
AE SCASB 7 Compare bytes AL-ES:[DI], update (E)DI
AF SCASW 7 Compare words AX-ES:[DI], update (E)DI
AF SCASD 7 Compare dwords EAX-ES:[DI], update (E)DI
Operation
IF AddressSize = 16
THEN use DI for dest-index;
ELSE (* AddressSize = 32 *) use EDI for dest-index;
FI;
IF byte type of instruction
THEN
AL - [dest-index]; (* Compare byte in AL and dest *)
IF DF = 0 THEN IndDec <- 1 ELSE IncDec <- -1; FI;
ELSE
IF OperandSize = 16
THEN
AX - [dest-index]; (* compare word in AL and dest *)
IF DF = 0 THEN IncDec <- 2 ELSE IncDec <- -2; FI;
ELSE (* OperandSize = 32 *)
EAX - [dest-index];(* compare dword in EAX & dest *)
IF DF = 0 THEN IncDec <- 4 ELSE IncDec <- -4; FI;
FI;
FI;
dest-index = dest-index + IncDec
<b>Description</b>
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.
<b>Flags Affected</b>
OF, SF, ZF, AF, PF, and CF as described in Appendix C
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
<b>Virtual 8086 Mode Exceptions</b>
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
<a name="17-03-SETcc"></a>
<h3>SETcc -- Byte Set on Condition</h3>
Opcode Instruction Clocks Description
0F 97 SETA r/m8 4/5 Set byte if above (CF=0 and ZF=0)
0F 93 SETAE r/m8 4/5 Set byte if above or equal (CF=0)
0F 92 SETB r/m8 4/5 Set byte if below (CF=1)
0F 96 SETBE r/m8 4/5 Set byte if below or equal (CF=1 or (ZF=1)
0F 92 SETC r/m8 4/5 Set if carry (CF=1)
0F 94 SETE r/m8 4/5 Set byte if equal (ZF=1)
0F 9F SETG r/m8 4/5 Set byte if greater (ZF=0 or SF=OF)
0F 9D SETGE r/m8 4/5 Set byte if greater or equal (SF=OF)
0F 9C SETL r/m8 4/5 Set byte if less (SF<>OF)
0F 9E SETLE r/m8 4/5 Set byte if less or equal (ZF=1 and
SF<>OF)
0F 96 SETNA r/m8 4/5 Set byte if not above (CF=1)
0F 92 SETNAE r/m8 4/5 Set byte if not above or equal (CF=1)
0F 93 SETNB r/m8 4/5 Set byte if not below (CF=0)
0F 97 SETNBE r/m8 4/5 Set byte if not below or equal (CF=0 and
ZF=0)
0F 93 SETNC r/m8 4/5 Set byte if not carry (CF=0)
0F 95 SETNE r/m8 4/5 Set byte if not equal (ZF=0)
0F 9E SETNG r/m8 4/5 Set byte if not greater (ZF=1 or SF<>OF)
0F 9C SETNGE r/m8 4/5 Set if not greater or equal (SF<>OF)
0F 9D SETNL r/m8 4/5 Set byte if not less (SF=OF)
0F 9F SETNLE r/m8 4/5 Set byte if not less or equal (ZF=1 and
SF<>OF)
0F 91 SETNO r/m8 4/5 Set byte if not overflow (OF=0)
0F 9B SETNP r/m8 4/5 Set byte if not parity (PF=0)
0F 99 SETNS r/m8 4/5 Set byte if not sign (SF=0)
0F 95 SETNZ r/m8 4/5 Set byte if not zero (ZF=0)
0F 90 SETO r/m8 4/5 Set byte if overflow (OF=1)
0F 9A SETP r/m8 4/5 Set byte if parity (PF=1)
0F 9A SETPE r/m8 4/5 Set byte if parity even (PF=1)
0F 9B SETPO r/m8 4/5 Set byte if parity odd (PF=0)
0F 98 SETS r/m8 4/5 Set byte if sign (SF=1)
0F 94 SETZ r/m8 4/5 Set byte if zero (ZF=1)
Operation
IF condition THEN r/m8 <- 1 ELSE r/m8 <- 0; FI;
<b>Description</b>
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.
<b>Flags Affected</b>
None
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
<b>Virtual 8086 Mode Exceptions</b>
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
<a name="17-03-SGDT"></a>
<h3>SGDT/SIDT -- Store Global/Interrupt Descriptor Table Register</h3>
Opcode Instruction Clocks Description
0F 01 /0 SGDT m 9 Store GDTR to m
0F 01 /1 SIDT m 9 Store IDTR to m
Operation
DEST <- 48-bit BASE/LIMIT register contents;
<b>Description</b>
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.
<b>Flags Affected</b>
None
<b>Protected Mode Exceptions</b>
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
<b>Real Address Mode Exceptions</b>
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
<b>Virtual 8086 Mode Exceptions</b>
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.
<a name="17-03-SHLD"></a>
<h3>SHLD -- Double Precision Shift Left</h3>
Opcode Instruction Clocks Description
0F A4 SHLD r/m16,r16,imm8 3/7 r/m16 gets SHL of r/m16 concatenated
with r16
0F A4 SHLD r/m32,r32,imm8 3/7 r/m32 gets SHL of r/m32 concatenated
with r32
0F A5 SHLD r/m16,r16,CL 3/7 r/m16 gets SHL of r/m16 concatenated
with r16
0F A5 SHLD r/m32,r32,CL 3/7 r/m32 gets SHL of r/m32 concatenated
with r32
Operation
(* count is an unsigned integer corresponding to the last operand of the
instruction, either an immediate byte or the byte in register CL *)
ShiftAmt <- count MOD 32;
inBits <- register; (* Allow overlapped operands *)
IF ShiftAmt = 0
THEN no operation
ELSE
IF ShiftAmt �erandSize
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;
<b>Description</b>
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.
<b>Flags Affected</b>
OF, SF, ZF, PF, and CF as described above; AF and OF are undefined
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
<b>Virtual 8086 Mode Exceptions</b>
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
<a name="17-03-SHRD"></a>
<h3>SHRD -- Double Precision Shift Right</h3>
Opcode Instruction Clocks Description
0F AC SHRD r/m16,r16,imm8 3/7 r/m16 gets SHR of r/m16 concatenated
with r16
0F AC SHRD r/m32,r32,imm8 3/7 r/m32 gets SHR of r/m32 concatenated
with r32
0F AD SHRD r/m16,r16,CL 3/7 r/m16 gets SHR of r/m16 concatenated
with r16
0F AD SHRD r/m32,r32,CL 3/7 r/m32 gets SHR of r/m32 concatenated
with r32
Operation
(* count is an unsigned integer corresponding to the last operand of the
instruction, either an immediate byte or the byte in register CL *)
ShiftAmt <- count MOD 32;
inBits <- register; (* Allow overlapped operands *)
IF ShiftAmt = 0
THEN no operation
ELSE
IF ShiftAmt �erandSize
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;
<b>Description</b>
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.
<b>Flags Affected</b>
OF, SF, ZF, PF, and CF as described above; AF and OF are undefined
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
<b>Virtual 8086 Mode Exceptions</b>
Same exceptions as in Real Address Mode; #PF(fault-code) for a page
fault
<a name="17-03-SLDT"></a>
<h3>SLDT -- Store Local Descriptor Table Register</h3>
Opcode Instruction Clocks Description
0F 00 /0 SLDT r/m16 pm=2/2 Store LDTR to EA word
Operation
r/m16 <- LDTR;
<b>Description</b>
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.
<b>Flags Affected</b>
None
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 6; SLDT is not recognized in Real Address Mode
<b>Virtual 8086 Mode Exceptions</b>
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.
<a name="17-03-SMSW"></a>
<h3>SMSW -- Store Machine Status Word</h3>
Opcode Instruction Clocks Description
0F 01 /4 SMSW r/m16 2/3,pm=2/2 Store machine status word to EA
word
Operation
r/m16 <- MSW;
<b>Description</b>
SMSW stores the machine status word (part of CR0) in the two-byte register
or memory location indicated by the effective address operand.
<b>Flags Affected</b>
None
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
<b>Virtual 8086 Mode Exceptions</b>
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.
<a name="17-03-STC"></a>
<h3>STC -- Set Carry Flag</h3>
Opcode Instruction Clocks Description
F9 STC 2 Set carry flag
Operation
CF <- 1;
<b>Description</b>
STC sets the carry flag to 1.
<b>Flags Affected</b>
CF = 1
<b>Protected Mode Exceptions</b>
None
<b>Real Address Mode Exceptions</b>
None
<b>Virtual 8086 Mode Exceptions</b>
None
<a name="17-03-STD"></a>
<h3>STD -- Set Direction Flag</h3>
Opcode Instruction Clocks Description
FD STD 2 Set direction flag so (E)SI and/or (E)DI
decrement
Operation
DF <- 1;
<b>Description</b>
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.
<b>Flags Affected</b>
DF = 1
<b>Protected Mode Exceptions</b>
None
<b>Real Address Mode Exceptions</b>
None
<b>Virtual 8086 Mode Exceptions</b>
None
<a name="17-03-STI"></a>
<h3>STI -- Set Interrupt Flag</h3>
Opcode Instruction Clocks Description
F13 STI 3 Set interrupt flag; interrupts enabled at the
end of the next instruction
Operation
IF <- 1
<b>Description</b>
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.
<b>Flags Affected</b>
IF = 1
<b>Protected Mode Exceptions</b>
#GP(0) if the current privilege level is greater (has less privilege) than
the I/O privilege level
<b>Real Address Mode Exceptions</b>
None
<b>Virtual 8086 Mode Exceptions</b>
None
<a name="17-03-STOS"></a>
<h3>STOS/STOSB/STOSW/STOSD -- Store String Data</h3>
Opcode Instruction Clocks Description
AA STOS m8 4 Store AL in byte ES:[(E)DI], update (E)DI
AB STOS m16 4 Store AX in word ES:[(E)DI], update (E)DI
AB STOS m32 4 Store EAX in dword ES:[(E)DI], update (E)DI
AA STOSB 4 Store AL in byte ES:[(E)DI], update (E)DI
AB STOSW 4 Store AX in word ES:[(E)DI], update (E)DI
AB STOSD 4 Store EAX in dword ES:[(E)DI], update (E)DI
Operation
IF AddressSize = 16
THEN use ES:DI for DestReg
ELSE (* AddressSize = 32 *) use ES:EDI for DestReg;
FI;
IF byte type of instruction
THEN
(ES:DestReg) <- AL;
IF DF = 0
THEN DestReg <- DestReg + 1;
ELSE DestReg <- DestReg - 1;
FI;
ELSE IF OperandSize = 16
THEN
(ES:DestReg) <- AX;
IF DF = 0
THEN DestReg <- DestReg + 2;
ELSE DestReg <- DestReg - 2;
FI;
ELSE (* OperandSize = 32 *)
(ES:DestReg) <- EAX;
IF DF = 0
THEN DestReg <- DestReg + 4;
ELSE DestReg <- DestReg - 4;
FI;
FI;
FI;
<b>Description</b>
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.
<b>Flags Affected</b>
None
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
<b>Virtual 8086 Mode Exceptions</b>
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
<a name="17-03-STR"></a>
<h3>STR -- Store Task Register</h3>
Opcode Instruction Clocks Description
0F 00 /1 STR r/m16 pm=23/27 Load EA word into task register
Operation
r/m <- task register;
<b>Description</b>
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.
<b>Flags Affected</b>
None
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 6; STR is not recognized in Real Address Mode
<b>Virtual 8086 Mode Exceptions</b>
Same exceptions as in Real Address Mode
Notes
The operand-size attribute has no effect on this instruction.
<a name="17-03-SUB"></a>
<h3>SUB -- Integer Subtraction</h3>
Opcode Instruction Clocks Description
2C ib SUB AL,imm8 2 Subtract immediate byte from AL
2D iw SUB AX,imm16 2 Subtract immediate word from AX
2D id SUB EAX,imm32 2 Subtract immediate dword from EAX
80 /5 ib SUB r/m8,imm8 2/7 Subtract immediate byte from r/m byte
81 /5 iw SUB r/m16,imm16 2/7 Subtract immediate word from r/m word
81 /5 id SUB r/m32,imm32 2/7 Subtract immediate dword from r/m
dword
83 /5 ib SUB r/m16,imm8 2/7 Subtract sign-extended immediate byte
from r/m word
83 /5 ib SUB r/m32,imm8 2/7 Subtract sign-extended immediate byte
from r/m dword
28 /r SUB r/m8,r8 2/6 Subtract byte register from r/m byte
29 /r SUB r/m16,r16 2/6 Subtract word register from r/m word
29 /r SUB r/m32,r32 2/6 Subtract dword register from r/m
dword
2A /r SUB r8,r/m8 2/7 Subtract byte register from r/m byte
2B /r SUB r16,r/m16 2/7 Subtract word register from r/m word
2B /r SUB r32,r/m32 2/7 Subtract dword register from r/m
dword
Operation
IF SRC is a byte and DEST is a word or dword
THEN DEST = DEST - SignExtend(SRC);
ELSE DEST <- DEST - SRC;
FI;
<b>Description</b>
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.
<b>Flags Affected</b>
OF, SF, ZF, AF, PF, and CF as described in Appendix C
<b>Protected Mode Exceptions</b>
#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
<b>Real Address Mode Exceptions</b>
Interrupt 13 if any part of the operand would lie outside of the effective
address space from 0 to 0FFFFH
<b>Virtual 8086 Mode Exceptions</b>
Same exceptions as in Real Address Mode; #PF(fault-code) for a page fault
<hr>
Prev: <a href="chp17-r3.htm">17.3.R 'R' Instructions </a>
Next: <a href="chp17-t3.htm">17.3.T 'T' Instructions </a>
</pre>
</body>
</html>
|