SAL, SAR, SHL, SHR
移动
stableVMJITAOTinstruction
编码
| 操作码 | 指令 | Op/En | 64 位 | 兼容/传统 | 说明 |
|---|---|---|---|---|---|
D0 /4 | SAL r/m8, 1 | M1 | 有效 | 有效 | 将r/m8乘以2,一次. |
D2 /4 | SAL r/m8, CL | MC | 有效 | 有效 | 将 r/m8 乘以 2, CL 倍数. |
C0 /4 ib | SAL r/m8, imm8 | MI | 有效 | 有效 | 将r/m8乘以2,imm8乘以2. |
D1 /4 | SAL r/m16, 1 | M1 | 有效 | 有效 | 将r/m16乘以2,一次. |
D3 /4 | SAL r/m16, CL | MC | 有效 | 有效 | 将 r/m16 乘以 2, CL 倍数. |
C1 /4 ib | SAL r/m16, imm8 | MI | 有效 | 有效 | 将r/m16乘以2,imm8乘以2. |
D1 /4 | SAL r/m3, 1 | M1 | 有效 | 有效 | 将r/m3乘以2,一次. |
REX.W + D1 /4 | SAL r/m64, 1 | M1 | 有效 | 不可编码 | 将r/m64乘以2,一次. |
D3 /4 | SAL r/m3, CL | MC | 有效 | 有效 | 将 r/m3 乘以 2, CL 倍数. |
REX.W + D3 /4 | SAL r/m64, CL | MC | 有效 | 不可编码 | 将 r/m64 乘以 2, CL 倍数. |
C1 /4 ib | SAL r/m3, imm8 | MI | 有效 | 有效 | 将r/m3乘以2,imm8乘以2. |
REX.W + C1 /4 ib | SAL r/m64, imm8 | MI | 有效 | 不可编码 | 将r/m64乘以2,imm8乘以2. |
D0 /7 | SAR r/m8, 1 | M1 | 有效 | 有效 | 签名除号3 r/m8乘以2,一次. |
D2 /7 | SAR r/m8, CL | MC | 有效 | 有效 | 已签名的除法 3 r/m8 乘以 2, CL 次 。 |
C0 /7 ib | SAR r/m8, imm8 | MI | 有效 | 有效 | 已签名的除法 3 r/m8 乘以 2, imm8 次 。 |
D1 /7 | SAR r/m16,1 | M1 | 有效 | 有效 | 签名除号3 r/m16乘以2,一次. |
D3 /7 | SAR r/m16, CL | MC | 有效 | 有效 | 已签名的除法 3 r/m16 乘以 2, CL 次 。 |
C1 /7 ib | SAR r/m16, imm8 | MI | 有效 | 有效 | 已签名的除法 3 r/m16 乘以 2, imm8 次 。 |
D1 /7 | SAR r/m3, 1 | M1 | 有效 | 有效 | 签名除号3 r/m3乘以2,一次. |
REX.W + D1 /7 | SAR r/m64, 1 | M1 | 有效 | 不可编码 | 签名除号3 r/m64乘以2,一次. |
D3 /7 | SAR r/m3, CL | MC | 有效 | 有效 | 已签名的除法 3 r/m3 乘以 2, CL 次 。 |
REX.W + D3 /7 | SAR r/m64, CL | MC | 有效 | 不可编码 | 已签名的除法 3 r/m64 乘以 2, CL 次 。 |
C1 /7 ib | SAR r/m3, imm8 | MI | 有效 | 有效 | 已签名的除法 3 r/m3 乘以 2, imm8 次 。 |
REX.W + C1 /7 ib | SAR r/m64, imm8 | MI | 有效 | 不可编码 | 已签名除号 3 r/m64 乘以 2 imm8 次 |
D0 /4 | SHL r/m8, 1 | M1 | 有效 | 有效 | 将r/m8乘以2,一次. |
D2 /4 | SHL r/m8, CL | MC | 有效 | 有效 | 将 r/m8 乘以 2, CL 倍数. |
C0 /4 ib | SHL r/m8, imm8 | MI | 有效 | 有效 | 将r/m8乘以2,imm8乘以2. |
D1 /4 | SHL r/m16,1 | M1 | 有效 | 有效 | 将r/m16乘以2,一次. |
D3 /4 | SHL r/m16, CL | MC | 有效 | 有效 | 将 r/m16 乘以 2, CL 倍数. |
C1 /4 ib | SHL r/m16, imm8 | MI | 有效 | 有效 | 将r/m16乘以2,imm8乘以2. |
D1 /4 | SHL r/m32,1 | M1 | 有效 | 有效 | 将r/m3乘以2,一次. |
REX.W + D1 /4 | SHL r/m64,1 | M1 | 有效 | 不可编码 | 将r/m64乘以2,一次. |
D3 /4 | SHL r/m3, CL | MC | 有效 | 有效 | 将 r/m3 乘以 2, CL 倍数. |
REX.W + D3 /4 | SHL r/m64, CL | MC | 有效 | 不可编码 | 将 r/m64 乘以 2, CL 倍数. |
C1 /4 ib | SHL r/m3, imm8 | MI | 有效 | 有效 | 将r/m3乘以2,imm8乘以2. |
REX.W + C1 /4 ib | SHL r/m64, imm8 | MI | 有效 | 不可编码 | 将r/m64乘以2,imm8乘以2. |
D0 /5 | SHR r/m82,1 | M1 | 有效 | 有效 | 未签名的r/m8除以2,一次. |
D2 /5 | SHR r/m8, CL | MC | 有效 | 有效 | 未签名将 r/m8 除以 2, CL 次 。 |
C0 /5 ib | SHR r/m8, imm8 | MI | 有效 | 有效 | 未签名将 r/m8 除以 2, imm8 次 。 |
D1 /5 | SHR r/m16, 1 | M1 | 有效 | 有效 | 未签名的r/m16除以2,一次. |
D3 /5 | SHR r/m16, CL | mc | 未签名的 r/m16 除以 2, CL 次 | ||
C1 /5 ib | SHR r/m16, imm8 | mi | 有效的无符号除以 r/m16 2, imm8 次 。 | ||
D1 /5 | SHR r/m3, 1 | m1 | 有效无符号除以 r/m3 2,一次. | ||
REX.W + D1 /5 | SHR r/m64, 1 | m1 | 有效 N.E. 未签名将 r/m64 除以 2,一次. | ||
D3 /5 | SHR r/m3, CL | mc | 有效无符号除以 r/m3 2, CL 乘数 。 | ||
REX.W + D3 /5 | SHR r/m64, CL | mc | 有效 N.E. 未签名的将 r/m64 除以 2, CL 次 。 | ||
C1 /5 ib | SHR r/m3, imm8 | mi | 有效的无符号除以 r/m3 2, imm8 次 。 | ||
REX.W + C1 /5 ib | SHR r/m64, imm8 | mi | 有效 N.E. 未签名将 r/m64 除以 2, imm8 次 。 |
操作数编码
每个模式对应上表 Op/En 列的一个取值,说明各操作数按书写顺序分别编码在指令的哪个字段,以及指令对它是读、是写还是两者兼有。
M1
modrm.rmlectura y escrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移1
MC
modrm.rmlectura y escrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移CL
MI
modrm.rmlectura y escrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移imm8指令后的立即数字节
实测开销
正在从 arch-data 加载实测数据...
涉及的标志位
CF进位PF奇偶AF辅助进位ZF零SF符号OF溢出
说明
将第一个 操作数 (目标操作数) 中的位移到左侧或右侧,以第二个 操作数 (count 操作数) 中指定的位数表示. 位移超越目标操作数边界的位移首先会转向CF旗,然后丢弃. 转向架操作结束后,CF旗中包含目标操作数中最后的位移.
目标操作数可以是寄存器或内存位置. 计数操作数可以是即时值或CL寄存器. 计数被遮掩到5位(或6位加64位的操作数). 计数范围以0至31为限(或63个有64位的操作数). 为1的计数提供了特殊的操作码编码.
左移算术(SAL)和左移逻辑(SHL)指令执行相同的操作;它们将目标操作数中的位移到左移(向更显著的位移位置). 对于每一班次计数,目标操作数中最显著的位移到CF旗中,最小的位移被清除(见Intel(R)64和IA-32架构软件开发者手册第1卷图7-7).
转动算术右侧(SAR)和转动逻辑右侧(SHR)指令将目标操作数的位移到右侧(转动不太显著的位移位置). 对于每个班次计数,目标操作数中最不重要的位移到CF旗中,而最显著的位移或者根据指令类型设置或者清除. SHR指令清除了最显著的位点(见Intel(R)64和IA-32架构软件开发者手册第1卷中的图7-8);SAR指令集或清除了最显著位点,以对应目标操作数中原值的符号(最显著位点). 实际上,SAR指令将空位位置的移位值用未移位值的符号填充(见Intel(R)64和IA-32架构软件开发者手册第1卷中的图7-9).
SAR 和 SHR 指令可以分别通过 2. 权限执行 目标操作数 的签名或未签名分割. 例如,使用 SAR 指令将一个签名的整数 1 位移到右边将值除以 2 。
使用 SAR 指令执行分区操作不会产生与 IDIV 指令相同的结果. 从 IDIV 指令的商号是四舍五入到零,而 SAR 指令的"引号"则是四舍五入到负无限。 这一差异仅对负数明显。 例如,当使用 IDIV 指令将 -9 乘以 4 时,结果为 -2,剩余为 -1. 如果使用 SAR 指令
移 -9 右转两个比特,结果为 -3,"剩余"为+3;然而,SAR指令只存储剩余中最显著的比特(在CF旗中).
OF旗只在1位移位时受到影响. 对于左转,如果结果中最显著的位点与CF旗相同(即原操作数的前两个位点是相同的),则OF旗设为0;否则则设为1. 对于SAR指令,所有1位移位的OF旗被清除. 对于SHR指令,OF旗被设定为原操作数中最显著的位.
在64位模式下,指令的默认操作大小为32位,CL的遮罩宽度为5位. 使用REX的前缀形式为REX.R,允许访问额外的注册(R8-R15). 使用REX前缀,形式为REX.W,促进运行到64位,并将CL的遮罩宽度设置到6位. 参见本节开头的汇总图,用于编码数据和限制.
IA-32 架构兼容性
8086型机车不遮挡值班计数. 然而,所有其他的IA-32处理器(从英特尔286处理器开始)都确实遮掩了转向计数到5位,导致最高计数为31位. 这种遮盖在所有操作模式(包括虚拟 8086 模式)中都做了,以减少指令的最大执行时间.
行动
IF OperandSize = 64
THEN
countMASK := 3FH;
ELSE
countMASK := 1FH;
FI
tempCOUNT := (COUNT AND countMASK);
origDEST := DEST;
tempDEST := DEST;
WHILE (tempCOUNT 0)
DO
IF instruction is SAL or SHL
THEN
CF := MSB(tempDEST);
ELSE (* Instruction is SAR or SHR *)
CF := LSB(tempDEST);
FI;
IF instruction is SAL or SHL
THEN
tempDEST := tempDEST 2;
ELSE
IF instruction is SAR
THEN
tempDEST := tempDEST / 2; (* Signed divide, rounding toward negative infinity *)
ELSE (* Instruction is SHR *)
tempDEST := tempDEST / 2 ; (* Unsigned divide *)
FI;
FI;
tempCOUNT := tempCOUNT 1;
OD;
(* Determine overflow for the various instructions *)
IF (COUNT and countMASK) = 1
THEN
IF instruction is SAL or SHL
THEN
OF := MSB(tempDEST) XOR CF;
ELSE
IF instruction is SAR
THEN
OF := 0;
ELSE (* Instruction is SHR *)
OF := MSB(origDEST);
FI;
FI;
ELSE IF (COUNT AND countMASK) = 0
THEN
All flags unchanged;
ELSE (* COUNT not 1 or 0 *)
OF := undefined;
FI;
FI;
DEST := tempDEST;受影响的旗帜
CF旗包含最后一个位移出目标操作数的值;对于SHL和SHR指令,在计数大于或等于目标操作数的大小(以位数计)时,它未定义. OF旗只为1位移位受到影响(见上文"描述");否则,则未定义. SF,ZF,PF的旗帜根据结果设置. 如果计数为0,则旗帜不受影响. 对于非零计数,AF旗没有定义.
异常
保护模式
#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 前缀 。 |