Plan 9 from Bell Labs’s /sys/src/pub/doc/intel/386/r.htm

Copyright © 2021 Plan 9 Foundation
Distributed under the MIT License.
Download the Plan 9 distribution.


<html>
<head>
<title>
17.3.R  'R' Instructions 
</title>
<body>
<pre>
<a name="17-03-R"></a>
Prev: <a href="chp17-p3.htm">17.3.P  'P' Instructions </a>
Next: <a href="chp17-s3.htm">17.3.S  'S' Instructions </a>
<hr>
<h2>
17.3.R  'R' Instructions 
</h2>

<a name="17-03-RCL"></a>
<h3>RCL/RCR/ROL/ROR -- Rotate</h3>


Opcode       Instruction       Clocks  Description

D0  /2       RCL r/m8,1        9/10    Rotate 9 bits (CF,r/m byte) left
                                       once
D2  /2       RCL r/m8,CL       9/10    Rotate 9 bits (CF,r/m byte) left CL
                                       times
C0  /2 ib    RCL r/m8,imm8     9/10    Rotate 9 bits (CF,r/m byte) left
                                       imm8 times
D1  /2       RCL r/m16,1       9/10    Rotate 17 bits (CF,r/m word) left
                                       once
D3  /2       RCL r/m16,CL      9/10    Rotate 17 bits (CF,r/m word) left
                                       CL times
C1  /2 ib    RCL r/m16,imm8    9/10    Rotate 17 bits (CF,r/m word) left
                                       imm8 times
D1  /2       RCL r/m32,1       9/10    Rotate 33 bits (CF,r/m dword) left
                                       once
D3  /2       RCL r/m32,CL      9/10    Rotate 33 bits (CF,r/m dword) left
                                       CL times
C1  /2 ib    RCL r/m32,imm8    9/10    Rotate 33 bits (CF,r/m dword) left
                                       imm8 times
D0  /3       RCR r/m8,1        9/10    Rotate 9 bits (CF,r/m byte) right
                                       once
D2  /3       RCR r/m8,CL       9/10    Rotate 9 bits (CF,r/m byte) right
                                       CL times
C0  /3 ib    RCR r/m8,imm8     9/10    Rotate 9 bits (CF,r/m byte) right
                                       imm8 times
D1  /3       RCR r/m16,1       9/10    Rotate 17 bits (CF,r/m word) right
                                       once
D3  /3       RCR r/m16,CL      9/10    Rotate 17 bits (CF,r/m word) right
                                       CL times
C1  /3 ib    RCR r/m16,imm8    9/10    Rotate 17 bits (CF,r/m word) right
                                       imm8 times
D1  /3       RCR r/m32,1       9/10    Rotate 33 bits (CF,r/m dword) right
                                       once
D3  /3       RCR r/m32,CL      9/10    Rotate 33 bits (CF,r/m dword) right
                                       CL times
C1  /3 ib    RCR r/m32,imm8    9/10    Rotate 33 bits (CF,r/m dword) right
                                       imm8 times
D0  /0       ROL r/m8,1        3/7     Rotate 8 bits r/m byte left once
D2  /0       ROL r/m8,CL       3/7     Rotate 8 bits r/m byte left CL
                                       times
C0  /0 ib    ROL r/m8,imm8     3/7     Rotate 8 bits r/m byte left imm8
                                       times
D1  /0       ROL r/m16,1       3/7     Rotate 16 bits r/m word left once
D3  /0       ROL r/m16,CL      3/7     Rotate 16 bits r/m word left CL
                                       times
C1  /0 ib    ROL r/m16,imm8    3/7     Rotate 16 bits r/m word left imm8
                                       times
D1  /0       ROL r/m32,1       3/7     Rotate 32 bits r/m dword left once
D3  /0       ROL r/m32,CL      3/7     Rotate 32 bits r/m dword left CL
                                       times
C1  /0 ib    ROL r/m32,imm8    3/7     Rotate 32 bits r/m dword left imm8
                                       times
D0  /1       ROR r/m8,1        3/7     Rotate 8 bits r/m byte right once
D2  /1       ROR r/m8,CL       3/7     Rotate 8 bits r/m byte right CL
                                       times
C0  /1 ib    ROR r/m8,imm8     3/7     Rotate 8 bits r/m word right imm8
                                       times
D1  /1       ROR r/m16,1       3/7     Rotate 16 bits r/m word right once
D3  /1       ROR r/m16,CL      3/7     Rotate 16 bits r/m word right CL
                                       times
C1  /1 ib    ROR r/m16,imm8    3/7     Rotate 16 bits r/m word right imm8
                                       times
D1  /1       ROR r/m32,1       3/7     Rotate 32 bits r/m dword right once
D3  /1       ROR r/m32,CL      3/7     Rotate 32 bits r/m dword right CL
                                       times
C1  /1 ib    ROR r/m32,imm8    3/7     Rotate 32 bits r/m dword right imm8
                                       times


Operation

(* ROL - Rotate Left *)
temp <- COUNT;
WHILE (temp <> 0)
DO
   tmpcf <- high-order bit of (r/m);
   r/m <- r/m * 2 + (tmpcf);
   temp <- temp - 1;
OD;
IF COUNT = 1
THEN
   IF high-order bit of r/m <> CF
   THEN OF <- 1;
   ELSE OF <- 0;
   FI;
ELSE OF <- undefined;
FI;
(* ROR - Rotate Right *)
temp <- COUNT;
WHILE (temp <> 0 )
DO
   tmpcf <- low-order bit of (r/m);
   r/m <- r/m / 2 + (tmpcf * 2^(width(r/m)));
   temp <- temp - 1;
DO;
IF COUNT = 1
THEN
   IF (high-order bit of r/m) <> (bit next to high-order bit of r/m)
   THEN OF <- 1;
   ELSE OF <- 0;
   FI;
ELSE OF <- undefined;
FI;

<b>Description</b>

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.

<b>Flags Affected</b>

OF only for single rotates; OF is undefined for multi-bit rotates; CF as
described above

<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-REP"></a>
<h3>REP/REPE/REPZ/REPNE/REPNZ -- Repeat Following String Operation</h3>


Opcode    Instruction         Clocks           Description

F3  6C    REP INS r/m8, DX    13+6*(E)CX,
                              pm=7+6*(E)CX
If CPL �PL/
                              27+6*(E)CX
If CPL > IOPL or if in virtual 8086 mode      Input (E)CX bytes from port
                                               DX into ES:[(E)DI]
F3  6D    REP INS r/m16,DX    13+6*(E)CX,
                              pm=7+6*(E)CX
If CPL �PL/
                              27+6*(E)CX
If CPL > IOPL or if in virtual 8086 mode      Input (E)CX words from port
                                               DX into ES:[(E)DI]
F3  6D    REP INS r/m32,DX    13+6*(E)CX,
                              pm=7+6*(E)CX
If CPL �PL/
                              27+6*(E)CX
If CPL > IOPL or if in virtual 8086 mode      Input (E)CX dwords from port
                                               DX into ES:[(E)DI]
F3  A4    REP MOVS m8,m8      5+4*(E)CX        Move (E)CX bytes from
                                               [(E)SI] to ES:[(E)DI]
F3  A5    REP MOVS m16,m16    5+4*(E)CX        Move (E)CX words from
                                               [(E)SI] to ES:[(E)DI]
F3  A5    REP MOVS m32,m32    5+4*(E)CX        Move (E)CX dwords from
                                               [(E)SI] to ES:[(E)DI]
F3  6E    REP OUTS DX,r/m8    5+12*(E)CX,
                              pm=6+5*(E)CX
If CPL �PL/
                              26+5*(E)CX
If CPL > IOPL or if in virtual 8086 mode      Output (E)CX bytes from
                                               [(E)SI] to port DX
F3  6F    REP OUTS DX,r/m16   5+12*(E)CX,
                              pm=6+5*(E)CX
If CPL �PL/
                              26+5*(E)CX
If CPL > IOPL or if in virtual 8086 mode      Output (E)CX words from
                                               [(E)SI] to port DX
F3  6F    REP OUTS DX,r/m32   5+12*(E)CX,
                              pm=6+5*(E)CX
If CPL �PL/
                              26+5*(E)CX
If CPL > IOPL or if in virtual 8086 mode      Output (E)CX dwords from
                                               [(E)SI] to port DX
F3  AA    REP STOS m8         5+5*(E)CX        Fill (E)CX bytes at
                                               ES:[(E)DI] with AL
F3  AB    REP STOS m16        5+5*(E)CX        Fill (E)CX words at
                                               ES:[(E)DI] with AX
F3  AB    REP STOS m32        5+5*(E)CX        Fill (E)CX dwords at
                                               ES:[(E)DI] with EAX
F3  A6    REPE CMPS m8,m8     5+9*N            Find nonmatching bytes in
                                               ES:[(E)DI] and [(E)SI]
F3  A7    REPE CMPS m16,m16   5+9*N            Find nonmatching words in
                                               ES:[(E)DI] and [(E)SI]
F3  A7    REPE CMPS m32,m32   5+9*N            Find nonmatching dwords in
                                               ES:[(E)DI] and [(E)SI]
F3  AE    REPE SCAS m8        5+8*N            Find non-AL byte starting
                                               at ES:[(E)DI]
F3  AF    REPE SCAS m16       5+8*N            Find non-AX word starting
                                               at ES:[(E)DI]
F3  AF    REPE SCAS m32       5+8*N            Find non-EAX dword starting
                                               at ES:[(E)DI]
F2  A6    REPNE CMPS m8,m8    5+9*N            Find matching bytes in
                                               ES:[(E)DI] and [(E)SI]
F2  A7    REPNE CMPS m16,m16  5+9*N            Find matching words in
                                               ES:[(E)DI] and [(E)SI]
F2  A7    REPNE CMPS m32,m32  5+9*N            Find matching dwords in
                                               ES:[(E)DI] and [(E)SI]
F2  AE    REPNE SCAS m8       5+8*N            Find AL, starting at
                                               ES:[(E)DI]
F2  AF    REPNE SCAS m16      5+8*N            Find AX, starting at
                                               ES:[(E)DI]
F2  AF    REPNE SCAS m32      5+8*N            Find EAX, starting at
                                               ES:[(E)DI]


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;

<b>Description</b>

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

<b>Flags Affected</b>

ZF by REP CMPS and REP SCAS as described above

<b>Protected Mode Exceptions</b>

#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

<b>Real Address Mode Exceptions</b>

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

<b>Virtual 8086 Mode Exceptions</b>

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


<a name="17-03-RET"></a>
<h3>RET -- Return from Procedure</h3>

Opcode     Instruction  Clocks         Description

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


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 �L 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 �L;
   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 �turn 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 �L, or DPL must be �L;
      FI;
   OD;

<b>Description</b>

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.

<b>Flags Affected</b>

None

<b>Protected Mode Exceptions</b>

#GP, #NP, or #SS, as described under "Operation" above; #PF(fault-code) for
a page fault

<b>Real Address Mode Exceptions</b>

Interrupt 13 if any part of the operand would be outside 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-p3.htm">17.3.P  'P' Instructions </a>
Next: <a href="chp17-s3.htm">17.3.S  'S' Instructions </a>
</pre>
</body>
</html>

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@plan9.bell-labs.com.