在 8088/86 上,CL 的 shift/rotate 是否会改变 CL 中的值?

On 8088/86, does a shift/rotate by CL alter the value in CL?

在 iAP88/86 文档中,移位和轮换的时间信息取决于 CL (p2-64) 中的移位计数。这似乎暗示它在 CL 中循环计数,进行那么多单位移位。

所以我的问题是,在 rotate/shift 完成后,CL 是否仍然具有相同的值,或者操作是否会倒计时,类似于 LOOP 指令的行为方式?

没有。 Shift/rotate 操作不会改变 cl。从英特尔的伪代码中可以清楚地看出这一点:

IF 64-Bit Mode and using REX.W
  THEN
    countMASK ← 3FH;
  ELSE
    countMASK ← 1FH;
  FI

  tempCOUNT ← (COUNT AND countMASK);
  tempDEST ← DEST;
  WHILE (tempCOUNT ≠ 0)
  DO
      IF instruction is SAL or SHL
        THEN
          CF ← MSB(DEST);
        ELSE (* Instruction is SAR or SHR *)
          CF ← LSB(DEST);
      FI;
      IF instruction is SAL or SHL
        THEN
          DEST ← DEST ∗ 2;
        ELSE
          IF instruction is SAR
            THEN
              DEST ← DEST / 2; (* Signed divide, rounding toward negative infinity *)
            ELSE (* Instruction is SHR *)
              DEST ← DEST / 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(DEST) XOR CF;
      ELSE
        IF instruction is SAR
          THEN
            OF ← 0;
          ELSE (* Instruction is SHR *)
            OF ← MSB(tempDEST);
        FI;
    FI;
  ELSE IF (COUNT AND countMASK) = 0
      THEN
        All flags unchanged;
      ELSE (* COUNT not 1 or 0 *)
        OF ← undefined;
    FI;
FI;

你可以清楚地看到,CL在循环之前赋值给了tempCOUNT,所以CL保持不变。

请注意,原始 8086 不会屏蔽移位计数,这会在移位计数是寄存器大小的倍数的情况下产生略有不同的结果。

一般来说,我建议您为您的仿真器提供 Intel 手册。他们详细说明了每条指令应该如何工作。

在 Intel 8088 上,按 CL 中的值移位或旋转会使 CL 保持不变。这些指令也是如此:RCL RCR ROL ROR SAL SAR SHL SHR

Intel 8088 上这些指令的语义在 iAPX 88 Book from July 1981 中指定。

以ROL进行阐述,语法为:ROL destination,count

编码规范确定了语义规范中使用的符号 COUNT 的值。对于相关指令形式,CL 的值分配给符号:

if v = 0 then COUNT = 1
else COUNT = (CL)

语义规范表明符号 COUNT 的值已分配给临时变量。寄存器 CL 永远不会改变。

(temp) ← COUNT
do while (temp) ≠ 0
  (CF) ← high-order bit of (EA)
  (EA) ← (EA) * 2 + (CF)
  (temp) ← (temp)-1
if COUNT = 1 then
  if high-order bit of (EA) ≠ (CF)
    then (OF) ← 1
  else (OF) ← 0
else (OF) undefined