2

这是什么意思:我只有 12 位用于立即常数,所以我可以只表示从 0 到 2^12 = 4096 的立即常数吗?操作数 2 如果是寄存器,可以有 32 位,但为什么立即数只有 12 位呢?这个数字是从哪里来的?

4

4 回答 4

5

它由指令集定义。例如,MOV指令被编码为

31 28 | 27 26 | 25 | 24 23 22 21 20 | 19   16 | 15    12 | 11        0      |
cond  | 0  0  | I  | 1  1  0  1  S  | SBZ     | Rd       | shifter operand  |

(see "ARM Architecture Reference Manual, 4.1.29 "MOV")

“立即”常量被编码在只有 12 位的“移位器操作数”中。其他指令有类似的定义有时是其他宽度。

存在此限制是因为 - 与 x86 不同 - ARM 上的指令在使用 Thumb(2) 时始终为 32 位或有时为 16 位。为了支持 12 位二进制数不能直接表示的值,移位器操作数允许不同的寻址模式(例如左移、右移、旋转)。

于 2013-11-19T12:50:09.067 回答
1

它在 ARM 指令中通常是这样的,例如ADD 和 SUB

imm12是 0-4095 范围内的任何值。

这样的指令通常是 4 字节,32 位,但你不需要那么多位来告诉核心从 2 个寄存器中提取并将结果放入另一个寄存器。因此指令集架构允许您以某种方式使用剩余位以避免额外的内存使用。例如,如果您要从寄存器中提取 256,则可以从堆栈中加载该 256(这是内存且速度较慢),或者您可以将其嵌入到指令中,这样会更快。当然,这种方法的缺点是空间有限,在这种情况下为 12 位,用于此类操作数的使用。

立即数常量所允许的值范围因指令而异,并且大多数时候汇编程序似乎将您的指令更改为其他指令以获得相同的效果 - 或者它提供伪指令来完成类似的工作(如ldr)。但是,有时它无法组装您的代码并失败。在这些情况下,最好回到ARM ARM并阅读有关嵌入立即常量的特定指令功能。

于 2013-11-19T12:54:44.187 回答
0

Arm 指令编码为 32 位长,与 x8086 指令中的指令编码不同,它是固定的。您不能在指令本身中编码任意 32 位常量。如果您查看 arm v7 指令集,对于算术指令,您可以直接在指令中编码一些32 位数字。这些数字被编码为 12 位(在指令中编码为 12 位的 32 位数字)。查看 arm 的架构手册。对不起,我没有给你的链接。

于 2013-11-20T05:50:46.893 回答
0

是的,只有 12 位可用,这意味着只能表示 2 12 = 4096 个不同的值。

这些状态可以以恒定的步长分布,即。从 0 到 4095(忽略负值),或者它们可以非线性分布。正如这里所解释的,ARM 体系结构使用 8 个最低有效位(256 个值)来表示一个数字,并使用 4 个最高有效位(16 个状态)以 2 的幂来放大或缩小这个数字。

由于这种缩放特性,ARM 体系结构能够表示许多有用的大数字,否则这些数字是无法表示的(即使是 16 位)。不幸的是,4096 个状态中的一些现在映射到与此处解释的相同的数字,因此这种方法只能表示 3073 个不同的值。

想要使用不在 3073 个有效立即数集合中的立即数的程序员可以使用需要多个时钟周期和/或内存的变通方法以获得所需的结果。

结论:这只是分配可用数字的一种不同方式,而不是使用 2 12 = 4096 个状态表示 2 32 = 4294967296 个不同数字的(神奇)方式!

于 2019-09-30T06:35:27.317 回答