我听说摩托罗拉68000和英特尔x86架构处理左移的溢出不同。特别是68k LSL与英特尔SAL / SHL汇编指令。
有谁知道这具体细节?他们设置不同的标志,还是设置不同的标志?我试着在参考手册中查看,但我没有看到任何区别。为什么人们想以不同的方式处理这种情况?
答案 0 :(得分:6)
不涉及X位。由于有两个左移指令,因此产生了对68000个标志的混淆:
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手册有详细说明:
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.
因此溢出标志的处理方式不同。如果乘以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位业务最终导致了更多的混乱而不是值得。