有三个基本转变:
英特尔同时拥有
sal
和 shl
,但它们映射到相同的操作码,而大多数其他架构似乎一开始就只有三个助记符。
您可以根据符号保留与不保留来重新构建网格:
但这产生了一种新的可能性,即“左移”且“符号保持”。这将具有保留符号位,但正常移动其余部分的行为。 现在我有几个问题:
这是
为了澄清,我所说的“符号保留”的意思是这样的,例如左移 1 和位宽度 8:
Not sign-preserving:
S A B C D E F G
/ / / / / / /
A B C D E F G 0
Sign-preserving:
S A B C D E F G
| / / / / / /
S B C D E F G 0
希望这有帮助!
有趣的事实:x86 有第二个未记录的左移操作码,例如d0 /4
和
d0 /6
均左移 1 个字节。 Sandpile 甚至声称一种是 SHL,一种是 SAL,但当前的 Intel x86 手册仅记录了 SAL 和 SHL 的
/4
编码。尚不清楚最初的 8086 是否实际上被设计为对同一操作的两个名称使用单独的操作码,或者别名操作码是否始终没有记录。 无论历史如何,现代
x86 不再记录单独的操作码。 (8 个指令与区分它们的 /r
字段共享相同的前导字节:ROL/ROR、RCL/RCR、SHL/SHR 和 SAL/SAR。将其他一些非移位指令粘贴到
/6
编码中会产生成本晶体管,并且使其出现故障可能还会花费更多晶体管,因此原始 8086 设计有左移冗余编码是有道理的,唯一的问题是历史上是否/如何记录它。)但这与实际问题完全无关:x86 的 SAL 不是
所询问的符号位保留移位。
的功能。 引用其“操作原理”(稍作修改以 ASCII 形式发布):
对于 SLAG,有符号的第三个操作数的 63 位数字部分左移第二个操作数地址 (Rn) 指定的位数,结果在其左侧附加第三个操作数的符号位,被放置在第一个操作数位置 (Rd)。(Rn - 输入,Rs - 移位计数,Rd - 输出。原文使用下标索引。)
对于 SLA,带符号的第一个操作数 (Rd) 的 31 位数字部分左移第二个操作数地址 (Rs) 指定的位数,并将结果放置在第一个操作数位置。通用寄存器 Rd 的位 0-31 保持不变。
(为此,请记住它们使用大端位编号,因此,0 = MSB。因此,32 位部分是位 32-63。)
并且,为了避免任何误读:
对于 SHIFT LEFT SINGLE(SLA 和 SLAK),从 31 到 63 的移位量会导致整个数字部分移出寄存器,留下最大负数或零的结果,具体取决于初始内容是否是消极的。对于 SHIFT LEFT SINGLE (SLAG),移位量 63 会产生相同的效果。
这肯定表明符号位保持不变。
一旦这一点没有在后来的 ISA 中得到支持(至少是主流),那么该功能的用处肯定被认为是不存在的。但这种架构在整个开发过程中都保留了细节。
对于溢出检测,IBM Z 保留 2 位条件代码,如果在操作中检测到溢出,则将 CC 设置为 3。