为什么 ARM LSL 与 LSR 的允许偏移值范围不同?

问题描述

为什么LSL的允许移位值为[0,31],LSR的允许移位值为[1,32]?

在 LSL 中移位 0 位对任何应用程序有何用处?为什么在 LSR 中不允许 0 shift?为什么 LSL 不允许 32 位移位?

解决方法

此限制适用于立即数移位。寄存器移位不受此类限制。

LSL 允许 0 表示“无移位”。这是一种特殊情况,标志设置指令的 C 标志没有被修改。

LSRASR by 0 的行为方式与 LSL by 0 相同,因此 CPU 设计者决定使立即操作数 0 表示移位 32,从而启用额外的功能。对于 ROR 的情况,移位 0 表示特殊的“向右旋转扩展”指令 RRX,因为旋转 32 不是很有用。

参考例如到 ARM7TDMI 数据表,它说:

注意 LSL #0 是一种特殊情况,其中移位器进位是 CPSR C 标志的旧值。 Rm 的内容直接用作第二个操作数。

可能预期对应于 LSR #0 的移位字段的形式用于编码 LSR #32,其结果为零,Rm 的第 31 位作为进位输出。逻辑右移零是多余的,因为它与逻辑左移零相同,因此汇编程序会将 LSR #0(以及 ASR #0 和 ROR #0)转换为 LSL #0,并允许指定 LSR #32。

可能会提供 ASR #0 的移位字段的形式用于对 ASR #32 进行编码。 Rm 的第 31 位再次用作进位输出,操作数 2 的每一位也等于 Rm 的第 31 位。因此,根据 Rm 的第 31 位的值,结果是全 1 或全 0。

可能会提供 ROR #0 的移位字段的形式用于对桶形移位器的特殊功能进行编码,即右旋转扩展 (RRX)。这是通过将 CPSR C 标志附加到 Rm [...] 内容的最高有效端而形成的 33 位数量的一位位置右循环。

在 Thumb (T32) 模式下,约定进行了调整。 Thumb 缺少明显的 MOVS Rd,Rn 指令,因此使用 LSLS Rd,Rn,#0 用于此目的。 LSR Rd,#imm5ASR Rd,#imm5 的行为方式与它们在 A32 模式下的行为方式相同。 #32 的立即数是通过将五位立即数字段设置为零来编码的。假设指令 ROR Rd,#imm5 不存在,因为它所在的操作码空间用于编码

ADDS Rd,Rm
SUBS Rd,Rm
ADDS Rd,#imm3
SUBS Rd,#imm3

相反。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...