RCL, RCR, ROL, ROR

旋转

stableVMJITAOTinstruction

编码

操作码指令Op/En64 位兼容/传统说明
D0 /2RCL r/m8, 1M1有效有效旋转 9 位( CF, r/m8) 一次 。
D2 /2RCL r/m8, CLMC有效有效旋转 9 位( CF, r/m8) 离开 CL 时间 。
C0 /2 ibRCL r/m8, imm8MI有效有效旋转 9 位( CF, r/m8) 离开 imm8 次 。
D1 /2RCL r/m16, 1M1有效有效旋转 17 位( CF, r/m16) 一次 。
D3 /2RCL r/m16, CLMC有效有效旋转 17 位( CF, r/m16) 离开 CL 时间 。
C1 /2 ibRCL r/m16, imm8MI有效有效旋转 17 位( CF, r/m16) 离开 imm8 次数 。
D1 /2RCL r/m3, 1M1有效有效旋转33位( CF, r/m3) 一次 。
REX.W + D1 /2RCL r/m64, 1M1有效不可编码旋转 65 位( CF, r/m64) 一次。 使用 6 位数 。
D3 /2RCL r/m3, CLMC有效有效旋转33位( CF, r/m3) 离开 CL 时间 。
REX.W + D3 /2RCL r/m64, CLMC有效不可编码旋转 65 位( CF, r/m64) 离开 CL 次。 使用 6 位数 。
C1 /2 ibRCL r/m3, imm8MI有效有效旋转33位(CF, r/m3),左转imm8次.
REX.W + C1 /2 ibRCL r/m64, imm8MI有效不可编码旋转 65 位( CF, r/m64) , 离开 imm8 次。 使用 6 位数 。
D0 /3RCR r/m8, 1M1有效有效旋转 9 位( CF, r/m8) 一次 。
D2 /3RCR r/m8, CLMC有效有效旋转 9 位( CF, r/m8) 右 CL 时间 。
C0 /3 ibRCR r/m8, imm8MI有效有效旋转 9 位( CF, r/m8) 右 imm8 次 。
D1 /3RCR r/m16, 1M1有效有效旋转 17 位( CF, r/m16) 一次 。
D3 /3RCR r/m16, CLMC有效有效旋转 17 位( CF, r/m16) 右 CL 时间 。
C1 /3 ibRCR r/m16, imm8MI有效有效旋转 17 位( CF, r/m16) 右 imm8 次 。
D1 /3RCR r/m3, 1M1有效有效旋转33位( CF, r/m3) 一次。 使用6位数 。
REX.W + D1 /3RCR r/m64, 1M1有效不可编码旋转 65 位( CF, r/m64) 一次。 使用 6 位数 。
D3 /3RCR r/m3, CLMC有效有效旋转33位( CF, r/m3) 右 CL 时间 。
REX.W + D3 /3RCR r/m64, CLMC有效不可编码旋转 65 位( CF, r/m64) 右 CL 次。 使用 6 位数 。
C1 /3 ibRCR r/m3, imm8MI有效有效旋转33位(CF, r/m3)右imm8次.
REX.W + C1 /3 ibRCR r/m64, imm8MI有效不可编码旋转 65 位( CF, r/m64) 右 imm8 次。 使用 6 位数 。
D0 /0ROL r/m8,2 1M1有效有效旋转 8 位 r/m8 一次 。
D2 /0ROL r/m8, CLMC有效有效旋转 8 位 r/m8 离开 CL 时间 。
C0 /0 ibROL r/m8, imm8MI有效有效旋转 8 位 r/m8 离开 imm8 次 。
D1 /0ROL r/m16, 1M1有效有效旋转 16 位 r/m16 一次 。
D3 /0ROL r/m16, CLMC有效有效旋转 16 位 r/m16 离开 CL 时间 。
C1 /0 ibROL r/m16, imm8MI有效有效旋转 16 位 r/m16 离开 imm8 次 。
D1 /0ROL r/m3, 1M1有效有效旋转 32 位 r/m3 一次 。
REX.W + D1 /0ROL r/m64, 1M1有效不可编码旋转 64 位 r/m64 一次。 使用 6 位数 。
D3 /0ROL r/m3, CLMC有效有效旋转 32 位 r/m3 离开 CL 时间 。
REX.W + D3 /0ROL r/m64, CLmc va盖上 N.E. 旋转 64 位 r/m64 离开 CL 时间。 使用 6 位数 。
C1 /0 ibROL r/m3, imm8mi va盖有效旋转 32 位 r/m3 离开 imm8 次 。
REX.W + C1 /0 ibROL r/m64, imm8mi va盖上 N.E. 旋转 64 位元 r/m64 离开 imm8 多次。 使用 6 位数 。
D0 /1ROR r/m8, 1m1 va盖有效旋转 8 位 r/m8 一次 。
D2 /1ROR r/m8, CLmc va盖有效旋转 8 位 r/m8 右 CL 次 。
C0 /1 ibROR r/m8, imm8mi va盖有效旋转 8 位 r/m16 右 imm8 次 。
D1 /1ROR r/m16, 1m1 va盖有效旋转 16 位 r/m16 右一次 。
D3 /1ROR r/m16, CLmc va盖有效旋转 16 比特 r/m16 右 CL 次 。
C1 /1 ibROR r/m16, imm8mi va盖有效旋转 16 比特的 r/m16 右 imm8 次数 。
D1 /1ROR r/m3, 1m1 va盖有效旋转 32 位 r/m3 右一次 。
REX.W + D1 /1ROR r/m64, 1m1 va盖上 N.E. 旋转64位 r/m64一次。 使用6位数 。
D3 /1ROR r/m3, CLmc va盖有效旋转 32 位 r/m3 右 CL 次 。
REX.W + D3 /1ROR r/m64, CLmc va盖上 N.E. 旋转 64 位 r/m64 右 CL 次。 使用 6 位数 。
C1 /1 ibROR r/m3, imm8mi va盖 有效旋转 32 位 r/m3 右 imm8 次 。
REX.W + C1 /1 ibROR r/m64, imm8mi va盖上 N.E. 旋转 64 位元右侧 r/m64 乘以 imm8 。 使用 6 位数 。

操作数编码

每个模式对应上表 Op/En 列的一个取值,说明各操作数按书写顺序分别编码在指令的哪个字段,以及指令对它是读、是写还是两者兼有。

M1

  1. modrm.rm escrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移
  2. 1

MC

  1. modrm.rm escrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移
  2. CL

MI

  1. modrm.rm escrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移
  2. imm8指令后的立即数字节

实测开销

正在从 arch-data 加载实测数据...

涉及的标志位

说明

移动(旋转)第一个操作数(目标操作数)的位数,在第二个操作数(count 操作数)中指定的位数,并将结果存储为目标操作数. 目标操作数可以是寄存器或内存位置;计数操作数是无符号的整数,可以是CL寄存器中的即时值或值. 计数被遮掩到5位(如果在64位模式和REX.W=1).

旋转左侧(ROL)和旋转左侧(RCL)指令将所有位移到更显著的位移位置,除了最显著位移到最小位移位置. 旋转的右侧(ROR)和旋转的右侧(RCR)指令将所有位移到不太显著的位移位置,除了最小位,它被旋转到最显著的位移位置.

RCL和RCR指令将CF旗包含在旋转中. RCL指令将CF旗转换为最小位,并将最显著位转换为CF旗. RCR指令将CF旗转换为最显著位,将最小位转换为CF旗. 对于ROL和ROR指令,CF旗的原始值不是结果的一部分,但CF旗收到从一端转向另一端的位元副本.

OF旗只定义于1位旋转;它在其他所有情况下(RCL和RCR指令除外:一个零位旋转无所作为,即影响任何旗帜)都没有定义. 对于左旋,OF旗被设定为CF位(旋转后)和结果中最显著位的独占的OR. 对于右旋,OF旗被设定为结果的两个最显著位的独占的OR.

在64位模式中,使用REX前缀的形式为REX.R允许访问额外的注册(R8-R15). 使用REX.W将第一个操作数推广到64位,并导致计数操作数成为6位计数器.

IA-32 架构兼容性

8086没有掩盖旋转计数. 然而,所有其他的IA-32处理器(从英特尔286处理器开始)确实将旋转计数遮掩到5位,结果最大计数为31位. 这种遮盖在所有操作模式(包括虚拟 8086 模式)中都做了,以减少指令的最大执行时间.

行动

(* RCL and RCR Instructions *)
SIZE := OperandSize;
CASE (determine count) OF

    SIZE := 8: tempCOUNT := (COUNT AND 1FH) MOD 9;
    SIZE := 16: tempCOUNT := (COUNT AND 1FH) MOD 17;
    SIZE := 32: tempCOUNT := COUNT AND 1FH;
    SIZE := 64: tempCOUNT := COUNT AND 3FH;
ESAC;
IF OperandSize = 64
    THEN COUNTMASK = 3FH;
    ELSE COUNTMASK = 1FH;
FI;

(* RCL Instruction Operation *)
tempDEST := DEST;
WHILE (tempCOUNT  0)

    DO
          tempCF := MSB(tempDEST);
         tempDEST := (tempDEST  2) + CF;
          CF := tempCF;
          tempCOUNT := tempCOUNT  1;

    OD;
ELIHW;
IF (COUNT & COUNTMASK) = 1

    THEN OF := MSB(tempDEST) XOR CF;
    ELSE OF is undefined;
FI;
DEST := tempDEST;


(* RCR Instruction Operation *)
tempDEST := DEST;
IF (COUNT & COUNTMASK) = 1

    THEN OF := MSB(tempDEST) XOR CF;
    ELSE OF is undefined;
FI;
WHILE (tempCOUNT  0)
    DO

          tempCF := LSB(SRC);
          tempDEST := (tempDEST / 2) + (CF * 2SIZE);
          CF := tempCF;
          tempCOUNT := tempCOUNT  1;
    OD;
DEST := tempDEST;

(* ROL Instruction Operation *)
tempCOUNT := (COUNT & COUNTMASK) MOD SIZE
tempDEST := DEST;

WHILE (tempCOUNT  0)

    DO
          tempCF := MSB(tempDEST);
         tempDEST := (tempDEST  2) + tempCF;
          tempCOUNT := tempCOUNT  1;

    OD;
ELIHW;
IF (COUNT & COUNTMASK)  0

    THEN CF := LSB(tempDEST);
FI;
IF (COUNT & COUNTMASK) = 1

    THEN OF := MSB(tempDEST) XOR CF;
    ELSE OF is undefined;
FI;
DEST := tempDEST;

(* ROR Instruction Operation *)
tempCOUNT := (COUNT & COUNTMASK) MOD SIZE
tempDEST := DEST;

WHILE (tempCOUNT  0)

    DO
          tempCF := LSB(SRC);
         tempDEST := (tempDEST / 2) + (tempCF  2SIZE);
          tempCOUNT := tempCOUNT  1;

    OD;
ELIHW;
IF (COUNT & COUNTMASK)  0

    THEN CF := MSB(tempDEST);
FI;
IF (COUNT & COUNTMASK) = 1

    THEN OF := MSB(tempDEST) XOR MSB - 1(tempDEST);
    ELSE OF is undefined;
FI;
DEST := tempDEST;

受影响的旗帜

对于RCL和RCR指令,零位旋转无所作为,即影响无旗. 对于ROL和ROR指令,如果蒙面计数为0,则旗子不受影响. 如果蒙面计数为1,则OF旗受到影响,否则(蒙面计数大于1),OF旗没有定义.

对于所有指令,当蒙面计数为非零时,CF旗会受到影响. SF,ZF,AF,和PF旗总是不受影响.

异常

保护模式
#GP(0)如果源运行符位于不可写入的区段中。如果内存运行符的有效地址位于 CS, DS, ES, FS, 或 GS 区段限制之外, 如果 DS, ES, FS, 或 GS 注册符包含 NULL 区段选择器 。
#SS(0)如果 内存操作数 有效地址在 SS 段限制之外. #PF(fault-code) 如果 页面错误 发生.
#AC(0)如果启用了对齐检查,并且在当前特权级别为3时会给出不对齐的内存引用.
#UD如果使用 LOCK 前缀 。
实地址模式
#GP如果内存操作数的有效地址在CS,DS,ES,FS或GS段限制之外.
#SS如果 内存操作数 的有效地址在 SS 段限制之外。
#UD如果使用 LOCK 前缀 。
虚拟 8086 模式
#GP(0)如果内存操作数的有效地址在CS,DS,ES,FS或GS段限制之外.
#SS(0)如果 内存操作数 有效地址在 SS 段限制之外. #PF(fault-code) 如果 页面错误 发生.
#AC(0)如果启用对齐检查, 并使用不对齐的内存引用 。
#UD如果使用 LOCK 前缀 。
兼容模式
与保护模式中的例外相同.
64 位模式
#SS(0)如果引用SS部分的内存地址是非冠状的.
#GP(0)如果 源操作数 位于不可写入的区段中。如果内存地址是非冠状的。 #PF(fault-code) 如果 页面错误 发生 。
#AC(0)如果启用了对齐检查,并且在当前特权级别为3时会给出不对齐的内存引用.
#UD如果使用 LOCK 前缀 。

来源