【问题标题】:why logical right shift and arithmetic right shift have a shift range of 1- 32 [duplicate]为什么逻辑右移和算术右移的移位范围为1-32 [重复]
【发布时间】:2013-06-25 05:45:30
【问题描述】:

我已经看到逻辑左移可以进行 1-31 位的移位。算术右移和逻辑右移以 1 -32 作为移位量。为什么左右移位有区别?

【问题讨论】:

  • 因为您可能希望将 0x80000000 和 shr 取 32 次以产生 0。但是取 0x00000001 并执行 lsh 32 次只会将设置位从末尾转储int,产生等价的整数溢出。
  • 请指定指令集
  • 指令集是arm v7

标签: assembly arm machine-code


【解决方案1】:

这与某些移位操作的特殊含义有关。来自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 的机器代码编码可以免费使用为了别的东西;因此他们将 LSR/ASR 的移位量为零解释为 32。

【讨论】:

    【解决方案2】:

    我相信这与 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,并且知道要移位的最后一位是什么,这些可能很有用,因为它将被移动到进位位。

    【讨论】:

      猜你喜欢
      • 2017-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-26
      • 1970-01-01
      • 1970-01-01
      • 2011-04-11
      相关资源
      最近更新 更多