3

我已经看到逻辑左移可以进行 1-31 位的移位。算术右移和逻辑右移以 1 -32 作为移位量。为什么右移和左移之间存在差异?

4

2 回答 2

3

它与某些移位操作的特殊含义有关。来自DDI 0029E(ARM7TDMI 数据表):

LSL #0 是一种特殊情况,其中移位器进位是 CPSR C 标志的旧值。Rm 的内容直接用作第二个操作数。
....
预期对应于 LSR #0 的移位字段的形式用于编码 LSR #32,其结果为零,Rm 的第 31 位作为进位输出。逻辑右移零是多余的,因为它与逻辑左移零相同,因此汇编器会将 LSR #0(以及 ASR #0 和 ROR #0)转换为 LSL #0,并允许指定 LSR #32。

换句话说,处理器设计者为 赋予了特殊含义LSL #0,这也意味着没有可能的编码,LSL #32因为 1..31 的移位量按原样解释,而 0 具有其特殊含义。 LSR #0并且ASR #0将由LSL #0汇编器转换为,因为它们具有相同的含义,这意味着机器代码编码LSR #0并可以自由用于ASR #0其他东西;因此他们将 0 的移位量解释为 32 LSR/ASR

于 2013-06-25T09:58:03.167 回答
0

我相信这与 ARM 桶形移位器有关。基本上 ARM 架构没有真正的移位指令。相反,它使您可以使用桶形移位器作为其他指令的一部分进行移位。

在处理接受移位的指令之前,处理器将检查是否指定了移位。如果不是,则应用的默认班次为 LSL #0。

现在,寄存器的移位量在指令中的 5 位字段或寄存器的底部字节上指定。然而,使用 5 位字段没有额外的开销,而使用寄存器则需要额外的周期。

5 位为您提供 32 个不同的值。因为当我们不想应用任何移位时我们需要一个 0 值,所以 LSL 的可能值范围是 0-31,而 LSR 和 ASR 的范围是 1-32,因为你永远不需要做 LSR # 0 或 ASR #0。

至于 LSR #32 或 ASR #32,如果您想用 0 或 1 设置寄存器并知道要移位的最后一位是什么,这些可能很有用,因为它将被移动到进位位。

于 2013-06-25T09:18:47.287 回答