这是什么意思:我只有12位立即常量,所以我能表示只有0到2 ^ 12 = 4096的立即数?操作数2,如果它是一个寄存器,可以有32位,但为什么只有12位立即常量?这个号码来自哪里?
答案 0 :(得分:3)
由指令集定义。例如。 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不同 - 使用Thumb(2)时,ARM上的指令始终为32位或有时为16位。为了支持不能用12位二进制数字直接表示的值,移位器操作数允许不同的寻址模式(例如左移,右移,旋转)。
答案 1 :(得分:1)
它通常在ARM指令中使用,例如ADD and SUB。
imm12 是0-4095范围内的任何值。
这样的指令通常是4个字节,32位,但你不需要那么多的位来告诉核心从2个寄存器中提取并将结果放到另一个寄存器中。因此,指令集架构允许您以某种方式使用剩余位,以避免额外的内存使用。例如,如果你要从寄存器中提取256,你可以从堆栈中加载256(这是内存和慢速),或者你可以将它嵌入到快速的指令中。当然,这种方法的缺点是有一个有限的空间,在这种情况下12比特用于这种操作数的使用。
立即常量允许的值范围在指令之间不同,并且大多数时候汇编程序似乎将您的指令更改为其他一些以获得相同的效果 - 或者它提供伪指令来执行类似的工作(如ldr)。然而,偶尔它无法组装您的代码并失败。在这些情况下,最好返回ARM ARM并阅读有关嵌入立即常量的特定指令功能。
答案 2 :(得分:0)
Arm指令编码长度为32位,与x8086指令中的指令编码不同,它是固定的。您不能在指令本身中编码任意32位常量。如果你看一下arm v7指令集,对于算术指令,你可以直接在指令中编码一些 32位数。这些数字被编码成12位(32位数字编码为12位指令) 。从arm.Sorry查看架构手册我没有给你链接。
答案 3 :(得分:0)
是的,只有12位可用,这意味着只能表示2 12 = 4096个不同的值。
这些状态可以以恒定步长分布,即。从0到4095(忽略负值),也可以非线性分布。如here所述,ARM体系结构使用8个最低有效位(256个值)表示一个数字,并使用4个最高有效位(16个状态)以2的幂放大或缩小该数字。>
借助此缩放属性,ARM体系结构能够表示很多有用的大数字,否则这些数字将无法表示(即使使用16位)。不幸的是,现在4096个州中的某些州映射到与所解释的here相同的数字,因此该方法只能表示3073个不同的值。
想要使用不在3073个有效立即数集中的立即数进行工作的程序员,可以使用需要多个时钟周期和/或内存的变通办法,以实现所需的结果。
结论:这只是分配可用数字的一种不同方式,而不是使用2 12 = 4096表示2 32 = 4294967296个不同数字的(魔术)方法状态!