SAL, SAR, SHL, SHR

移动

stableVMJITAOTinstruction

编码

操作码指令Op/En64 位兼容/传统说明
D0 /4SAL r/m8, 1M1有效有效将r/m8乘以2,一次.
D2 /4SAL r/m8, CLMC有效有效将 r/m8 乘以 2, CL 倍数.
C0 /4 ibSAL r/m8, imm8MI有效有效将r/m8乘以2,imm8乘以2.
D1 /4SAL r/m16, 1M1有效有效将r/m16乘以2,一次.
D3 /4SAL r/m16, CLMC有效有效将 r/m16 乘以 2, CL 倍数.
C1 /4 ibSAL r/m16, imm8MI有效有效将r/m16乘以2,imm8乘以2.
D1 /4SAL r/m3, 1M1有效有效将r/m3乘以2,一次.
REX.W + D1 /4SAL r/m64, 1M1有效不可编码将r/m64乘以2,一次.
D3 /4SAL r/m3, CLMC有效有效将 r/m3 乘以 2, CL 倍数.
REX.W + D3 /4SAL r/m64, CLMC有效不可编码将 r/m64 乘以 2, CL 倍数.
C1 /4 ibSAL r/m3, imm8MI有效有效将r/m3乘以2,imm8乘以2.
REX.W + C1 /4 ibSAL r/m64, imm8MI有效不可编码将r/m64乘以2,imm8乘以2.
D0 /7SAR r/m8, 1M1有效有效签名除号3 r/m8乘以2,一次.
D2 /7SAR r/m8, CLMC有效有效已签名的除法 3 r/m8 乘以 2, CL 次 。
C0 /7 ibSAR r/m8, imm8MI有效有效已签名的除法 3 r/m8 乘以 2, imm8 次 。
D1 /7SAR r/m16,1M1有效有效签名除号3 r/m16乘以2,一次.
D3 /7SAR r/m16, CLMC有效有效已签名的除法 3 r/m16 乘以 2, CL 次 。
C1 /7 ibSAR r/m16, imm8MI有效有效已签名的除法 3 r/m16 乘以 2, imm8 次 。
D1 /7SAR r/m3, 1M1有效有效签名除号3 r/m3乘以2,一次.
REX.W + D1 /7SAR r/m64, 1M1有效不可编码签名除号3 r/m64乘以2,一次.
D3 /7SAR r/m3, CLMC有效有效已签名的除法 3 r/m3 乘以 2, CL 次 。
REX.W + D3 /7SAR r/m64, CLMC有效不可编码已签名的除法 3 r/m64 乘以 2, CL 次 。
C1 /7 ibSAR r/m3, imm8MI有效有效已签名的除法 3 r/m3 乘以 2, imm8 次 。
REX.W + C1 /7 ibSAR r/m64, imm8MI有效不可编码已签名除号 3 r/m64 乘以 2 imm8 次
D0 /4SHL r/m8, 1M1有效有效将r/m8乘以2,一次.
D2 /4SHL r/m8, CLMC有效有效将 r/m8 乘以 2, CL 倍数.
C0 /4 ibSHL r/m8, imm8MI有效有效将r/m8乘以2,imm8乘以2.
D1 /4SHL r/m16,1M1有效有效将r/m16乘以2,一次.
D3 /4SHL r/m16, CLMC有效有效将 r/m16 乘以 2, CL 倍数.
C1 /4 ibSHL r/m16, imm8MI有效有效将r/m16乘以2,imm8乘以2.
D1 /4SHL r/m32,1M1有效有效将r/m3乘以2,一次.
REX.W + D1 /4SHL r/m64,1M1有效不可编码将r/m64乘以2,一次.
D3 /4SHL r/m3, CLMC有效有效将 r/m3 乘以 2, CL 倍数.
REX.W + D3 /4SHL r/m64, CLMC有效不可编码将 r/m64 乘以 2, CL 倍数.
C1 /4 ibSHL r/m3, imm8MI有效有效将r/m3乘以2,imm8乘以2.
REX.W + C1 /4 ibSHL r/m64, imm8MI有效不可编码将r/m64乘以2,imm8乘以2.
D0 /5SHR r/m82,1M1有效有效未签名的r/m8除以2,一次.
D2 /5SHR r/m8, CLMC有效有效未签名将 r/m8 除以 2, CL 次 。
C0 /5 ibSHR r/m8, imm8MI有效有效未签名将 r/m8 除以 2, imm8 次 。
D1 /5SHR r/m16, 1M1有效有效未签名的r/m16除以2,一次.
D3 /5SHR r/m16, CLmc未签名的 r/m16 除以 2, CL 次
C1 /5 ibSHR r/m16, imm8mi有效的无符号除以 r/m16 2, imm8 次 。
D1 /5SHR r/m3, 1m1有效无符号除以 r/m3 2,一次.
REX.W + D1 /5SHR r/m64, 1m1有效 N.E. 未签名将 r/m64 除以 2,一次.
D3 /5SHR r/m3, CLmc有效无符号除以 r/m3 2, CL 乘数 。
REX.W + D3 /5SHR r/m64, CLmc有效 N.E. 未签名的将 r/m64 除以 2, CL 次 。
C1 /5 ibSHR r/m3, imm8mi有效的无符号除以 r/m3 2, imm8 次 。
REX.W + C1 /5 ibSHR r/m64, imm8mi有效 N.E. 未签名将 r/m64 除以 2, imm8 次 。

操作数编码

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

M1

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

MC

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

MI

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

实测开销

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

涉及的标志位

说明

将第一个 操作数 (目标操作数) 中的位移到左侧或右侧,以第二个 操作数 (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 前缀 。

来源