68k / x86左移溢出?

时间:2009-11-11 03:05:45

标签: assembly x86 shift 68000

我听说摩托罗拉68000和英特尔x86架构处理左移的溢出不同。特别是68k LSL与英特尔SAL / SHL汇编指令。

有谁知道这具体细节?他们设置不同的标志,还是设置不同的标志?我试着在参考手册中查看,但我没有看到任何区别。为什么人们想以不同的方式处理这种情况?

3 个答案:

答案 0 :(得分:6)

不涉及X位。由于有两个左移指令,因此产生了对68000个标志的混淆:

  • LSL,逻辑左移,清除溢出标志。
  • ASL,算术左移,如果MSB在换班期间随时改变符号,则设置V标志。

x86指令集几乎没有那么强大。如果移位计数= 1,则OF,溢出标志=(MSB XOR CF),即如果MSB由于1位移位而改变符号,则OF = 1,否则OF = 0。

如果班次计数> 1,则OF 未定义。HTML extract of Intel's documentation for SHL)。

答案 1 :(得分:4)

程序员的CPU手册有详细说明:

Motorola 68K

X — Set according to the last bit shifted out of the operand; 
    unaffected for a shift count of zero. 
N — Set if the result is negative; cleared otherwise. 
Z  — Set if the result is zero; cleared otherwise. 
V — Always cleared. 
C — Set according to the last bit shifted out of the operand; 
    cleared for a shift count of zero. 

Intel x86

  • CF标志包含从目标操作数移出的最后一位的值;对于SHL和SHR指令,它是未定义的,其中计数大于或等于目标操作数的大小(以位为单位)。
  • OF标志仅受1位移位影响(参见上面的“说明”);否则,它是未定义的。
  • 根据结果设置SF,ZF和PF标志。如果计数为0,则标志不受影响。
  • 对于非零计数,AF标志未定义。

因此溢出标志的处理方式不同。如果乘以2(左移一位)导致溢出,它会在x86中通知你。我不知道为什么它只对1位移位如此具体。我猜(并且只是猜测)OF标志根据'last'位移设置 - 这可能不表示整个操作是否溢出,因此Intel只是将其记录为'undefined'。

答案 2 :(得分:3)

(是的,我正在审查1979年的摩托罗拉68000参考资料。)

你可能想到的是68000的相当奇怪的X位。 eXtend位本质上是C(进位)位的副本,但不受非算术指令的影响。 例如,假设您要添加12个字的整数。在x86中,您可能会看到类似的内容:

  .
  .
loop:
  ADC AX,[SI]    ; recycle carry-out from last iter as carry-in to this one

  LEA SI, [SI+2] ; flags untouched
  INC BX         ; BX is loop index.  sets all flags except CF
  CMP BX, 12     ; doh, changes carry (BUG)
  JB  loop

此代码不起作用,因为比较指令会破坏进位标志。这是loop指令在历史上有用的一个原因,在不修改标志的情况下将CX计数降至零。使用dec / jnz计数到零也可以,但会在现代x86上导致部分标记停顿。不幸的是loop is slow now too,所以从大约486到Sandybridge都没有好办法制作这样的循环。

但是在68000:

  .
  .
loop:
  ADDX.W (A0)+, D0   ; both C and X set the same
  INC.W  D7          ; D7 is loop index
  CMP.W  #12, D7     ; harms C, but X left intact
  BCC  loop

摩托罗拉认为他们对程序员有帮助,但X位业务最终导致了更多的混乱而不是值得。