RCL, RCR, ROL, ROR
旋转
stableVMJITAOTinstruction
编码
| 操作码 | 指令 | Op/En | 64 位 | 兼容/传统 | 说明 |
|---|---|---|---|---|---|
D0 /2 | RCL r/m8, 1 | M1 | 有效 | 有效 | 旋转 9 位( CF, r/m8) 一次 。 |
D2 /2 | RCL r/m8, CL | MC | 有效 | 有效 | 旋转 9 位( CF, r/m8) 离开 CL 时间 。 |
C0 /2 ib | RCL r/m8, imm8 | MI | 有效 | 有效 | 旋转 9 位( CF, r/m8) 离开 imm8 次 。 |
D1 /2 | RCL r/m16, 1 | M1 | 有效 | 有效 | 旋转 17 位( CF, r/m16) 一次 。 |
D3 /2 | RCL r/m16, CL | MC | 有效 | 有效 | 旋转 17 位( CF, r/m16) 离开 CL 时间 。 |
C1 /2 ib | RCL r/m16, imm8 | MI | 有效 | 有效 | 旋转 17 位( CF, r/m16) 离开 imm8 次数 。 |
D1 /2 | RCL r/m3, 1 | M1 | 有效 | 有效 | 旋转33位( CF, r/m3) 一次 。 |
REX.W + D1 /2 | RCL r/m64, 1 | M1 | 有效 | 不可编码 | 旋转 65 位( CF, r/m64) 一次。 使用 6 位数 。 |
D3 /2 | RCL r/m3, CL | MC | 有效 | 有效 | 旋转33位( CF, r/m3) 离开 CL 时间 。 |
REX.W + D3 /2 | RCL r/m64, CL | MC | 有效 | 不可编码 | 旋转 65 位( CF, r/m64) 离开 CL 次。 使用 6 位数 。 |
C1 /2 ib | RCL r/m3, imm8 | MI | 有效 | 有效 | 旋转33位(CF, r/m3),左转imm8次. |
REX.W + C1 /2 ib | RCL r/m64, imm8 | MI | 有效 | 不可编码 | 旋转 65 位( CF, r/m64) , 离开 imm8 次。 使用 6 位数 。 |
D0 /3 | RCR r/m8, 1 | M1 | 有效 | 有效 | 旋转 9 位( CF, r/m8) 一次 。 |
D2 /3 | RCR r/m8, CL | MC | 有效 | 有效 | 旋转 9 位( CF, r/m8) 右 CL 时间 。 |
C0 /3 ib | RCR r/m8, imm8 | MI | 有效 | 有效 | 旋转 9 位( CF, r/m8) 右 imm8 次 。 |
D1 /3 | RCR r/m16, 1 | M1 | 有效 | 有效 | 旋转 17 位( CF, r/m16) 一次 。 |
D3 /3 | RCR r/m16, CL | MC | 有效 | 有效 | 旋转 17 位( CF, r/m16) 右 CL 时间 。 |
C1 /3 ib | RCR r/m16, imm8 | MI | 有效 | 有效 | 旋转 17 位( CF, r/m16) 右 imm8 次 。 |
D1 /3 | RCR r/m3, 1 | M1 | 有效 | 有效 | 旋转33位( CF, r/m3) 一次。 使用6位数 。 |
REX.W + D1 /3 | RCR r/m64, 1 | M1 | 有效 | 不可编码 | 旋转 65 位( CF, r/m64) 一次。 使用 6 位数 。 |
D3 /3 | RCR r/m3, CL | MC | 有效 | 有效 | 旋转33位( CF, r/m3) 右 CL 时间 。 |
REX.W + D3 /3 | RCR r/m64, CL | MC | 有效 | 不可编码 | 旋转 65 位( CF, r/m64) 右 CL 次。 使用 6 位数 。 |
C1 /3 ib | RCR r/m3, imm8 | MI | 有效 | 有效 | 旋转33位(CF, r/m3)右imm8次. |
REX.W + C1 /3 ib | RCR r/m64, imm8 | MI | 有效 | 不可编码 | 旋转 65 位( CF, r/m64) 右 imm8 次。 使用 6 位数 。 |
D0 /0 | ROL r/m8,2 1 | M1 | 有效 | 有效 | 旋转 8 位 r/m8 一次 。 |
D2 /0 | ROL r/m8, CL | MC | 有效 | 有效 | 旋转 8 位 r/m8 离开 CL 时间 。 |
C0 /0 ib | ROL r/m8, imm8 | MI | 有效 | 有效 | 旋转 8 位 r/m8 离开 imm8 次 。 |
D1 /0 | ROL r/m16, 1 | M1 | 有效 | 有效 | 旋转 16 位 r/m16 一次 。 |
D3 /0 | ROL r/m16, CL | MC | 有效 | 有效 | 旋转 16 位 r/m16 离开 CL 时间 。 |
C1 /0 ib | ROL r/m16, imm8 | MI | 有效 | 有效 | 旋转 16 位 r/m16 离开 imm8 次 。 |
D1 /0 | ROL r/m3, 1 | M1 | 有效 | 有效 | 旋转 32 位 r/m3 一次 。 |
REX.W + D1 /0 | ROL r/m64, 1 | M1 | 有效 | 不可编码 | 旋转 64 位 r/m64 一次。 使用 6 位数 。 |
D3 /0 | ROL r/m3, CL | MC | 有效 | 有效 | 旋转 32 位 r/m3 离开 CL 时间 。 |
REX.W + D3 /0 | ROL r/m64, CL | mc va | 盖上 N.E. 旋转 64 位 r/m64 离开 CL 时间。 使用 6 位数 。 | ||
C1 /0 ib | ROL r/m3, imm8 | mi va | 盖有效旋转 32 位 r/m3 离开 imm8 次 。 | ||
REX.W + C1 /0 ib | ROL r/m64, imm8 | mi va | 盖上 N.E. 旋转 64 位元 r/m64 离开 imm8 多次。 使用 6 位数 。 | ||
D0 /1 | ROR r/m8, 1 | m1 va | 盖有效旋转 8 位 r/m8 一次 。 | ||
D2 /1 | ROR r/m8, CL | mc va | 盖有效旋转 8 位 r/m8 右 CL 次 。 | ||
C0 /1 ib | ROR r/m8, imm8 | mi va | 盖有效旋转 8 位 r/m16 右 imm8 次 。 | ||
D1 /1 | ROR r/m16, 1 | m1 va | 盖有效旋转 16 位 r/m16 右一次 。 | ||
D3 /1 | ROR r/m16, CL | mc va | 盖有效旋转 16 比特 r/m16 右 CL 次 。 | ||
C1 /1 ib | ROR r/m16, imm8 | mi va | 盖有效旋转 16 比特的 r/m16 右 imm8 次数 。 | ||
D1 /1 | ROR r/m3, 1 | m1 va | 盖有效旋转 32 位 r/m3 右一次 。 | ||
REX.W + D1 /1 | ROR r/m64, 1 | m1 va | 盖上 N.E. 旋转64位 r/m64一次。 使用6位数 。 | ||
D3 /1 | ROR r/m3, CL | mc va | 盖有效旋转 32 位 r/m3 右 CL 次 。 | ||
REX.W + D3 /1 | ROR r/m64, CL | mc va | 盖上 N.E. 旋转 64 位 r/m64 右 CL 次。 使用 6 位数 。 | ||
C1 /1 ib | ROR r/m3, imm8 | mi va | 盖 有效旋转 32 位 r/m3 右 imm8 次 。 | ||
REX.W + C1 /1 ib | ROR r/m64, imm8 | mi va | 盖上 N.E. 旋转 64 位元右侧 r/m64 乘以 imm8 。 使用 6 位数 。 |
操作数编码
每个模式对应上表 Op/En 列的一个取值,说明各操作数按书写顺序分别编码在指令的哪个字段,以及指令对它是读、是写还是两者兼有。
M1
modrm.rmescrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移1
MC
modrm.rmescrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移CL
MI
modrm.rmescrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移imm8指令后的立即数字节
实测开销
正在从 arch-data 加载实测数据...
涉及的标志位
CF进位PF奇偶AF辅助进位ZF零SF符号OF溢出
说明
移动(旋转)第一个操作数(目标操作数)的位数,在第二个操作数(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 前缀 。 |