what does it mean : I have only 12 bits for immediate constants, so can I represent immediate constants only from 0 to 2^12 = 4096 ? Operand 2 , if it's a register, can have 32 bits, but why only 12 bits for immediate constants? Where does this number come from?

- 328,167
- 45
- 605
- 847

- 3,320
- 8
- 43
- 80
-
1Because if it had 32bits, there would only be one instruction. The number is arbitrary. It is a balance between having enough op-codes to do something useful and giving a user enough range of constants. The `ldr rX, =constant` is another form you may be interested in. The value 4096 gives a 'three byte' mask in two instructions. The `ldr rx, =constant` maybe looked at as a 64-bit instruction to load a 32bit value. – artless noise Nov 19 '13 at 14:32
-
1same reason why mips can only have 16. fixed instruction length – old_timer Nov 19 '13 at 20:34
-
the `ldr rX, =constant` term is just a helper statement for the assembler and will not be converted into machine code directly. When `constant` can be expressed with 12 bits, it translates to `mov rX, #constant`. When not, the value is stored somewhere in the near an assembler generates `ldr rX, [pc, #offset]` – ensc Nov 19 '13 at 21:36
-
@ensc That is exactly my point. Use `ldr rX, =constant`. If it needs more than 12bits, it is 64bits in code space... which you can think of as a 64bit instruction. I know they are not in sequence, but they will be located close by. Only someone concerned with cache effects would care. Generally you should load constants outside of a hot path. The *area* is emitted with `.ltorg` and is generally called the *literal pool*. – artless noise Nov 19 '13 at 21:58
-
See also: http://stackoverflow.com/questions/17297695/intel-x86-to-arm-assembly-conversion, http://stackoverflow.com/questions/17214962/what-is-the-difference-between-label-and-label-in-armv6-assembly, http://stackoverflow.com/questions/14046686/ldr-vs-mov-arm-assembly, http://stackoverflow.com/questions/9374703/llvm-gcc-assembler-ldr-syntax, http://stackoverflow.com/questions/9735169/iphone-assembly-compilation-error-with-ldr-parameters – artless noise Nov 19 '13 at 22:09
-
@artlessnoise basically, it is correct. But I do not agree in seeing this as a "64-bit instruction". I am not sure whether it allowed to combine multiple `ldr rX, =val` with the same `val` (e.g. to load from same address in code space); this would make such an `ldr` effectively an 32 + 32/
bit instruction. – ensc Nov 19 '13 at 22:25 -
@ensc You have verified my close reason. Although there are five other questions that are near duplicates. – artless noise Nov 19 '13 at 23:04
-
@dwelch MIPS and most other 32/64-bit RISC architectures have 32-bit instruction. But there's MIPS16e which is an extension to reduce code length with the trade-off of speed, like ARM thumb – phuclv Jan 16 '14 at 23:56
-
sure, I have programmed using the mips 16e as well – old_timer Jan 17 '14 at 00:31
4 Answers
It defined by the instruction set. E.g. the MOV
instruction is encoded as
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")
"Immediate" constants are encoded in the "shifter operand" which is 12 bits only. Other instructions have similar definitions are sometimes other widths.
This limitation exists because -- unlike on x86 -- instructions on ARM are always 32 bit or sometimes 16 bit when using Thumb(2). To support values which can not be expressed directly by a 12 bit binary digit, the shifter operand allows different addressing modes (e.g. left-shift, right-shift, rotating).

- 6,704
- 14
- 22
-
-
-
I think it is also wrong to say immediate constants are just "encoded in the shifter operand". There are many types of immediate constants and the one you describe is not the one mentioned in the question. What you mentioned is called "Modified immediate constants" A5.2.4. What question asks is more related to imm12, which allows constants in the range of [0-4095]. – auselen Nov 19 '13 at 14:20
-
Question does not mention the instruction or the type at all. But ok; answer is incorrect regarding range of value and I will fix it. – ensc Nov 19 '13 at 14:28
-
ok but from what kind of register does this immediate come from? I mean what register is this? 1-12 are regular ones, and 13,14,15 are reserved for other functions I think... – MMMM Nov 19 '13 at 21:06
-
the immediate value is a value which can be expressed with 12 bits. E.g. like in `mov r0, #0x23` or `mov r1, #0x42000`. – ensc Nov 19 '13 at 21:33
It generally goes like this in ARM instructions, for example ADD and SUB.
imm12 is any value in the range 0-4095.
Such instruction is generally 4 bytes, 32bits but you wouldn't need that much bits to tell core to do extraction from 2 registers and put the result into another one. So instruction set architecture allows you to use remaining bits in a way to avoid extra memory usage. For example if you are going to extract 256 from a register, you could load that 256 from stack (which is memory and slow) or you could have it embedded in instruction which would be fast. Of course down side of such approach is to have a limited space, 12bits in this case for such operand usage.
Value range allowed by immediate constants differ among instructions and most of the time assembler seemingly changes your instruction into some other to get the same effect - or it provides pseudo instructions to do similar work (like ldr) . However now and then it fails to assemble your code and fails. In those cases it is best to go back ARM ARM and read about that specific instructions capabilities in regards to embedding immediate constants.

- 27,577
- 7
- 73
- 114
Arm instruction encoding is 32 bit long and it is fixed unlike instruction encoding in x8086 instructions . You cannot have a arbitrary 32 bit constant encoded in instruction itself. If you look into arm v7 instruction set ,for arithmetic instructions you can have some 32 bit numbers encoded in instruction directly.Such numbers are encoded into 12 bits (a 32 bit number encoded as 12 bit in instruction). Look into architecture manual from arm.Sorry i do not have a link for you .

- 375
- 2
- 6
- 23
Yes the fact that only 12 bits are available means that only 212 = 4096 distinct values can be represented.
These states can either be distributed with a constant step size ie. from 0 to 4095 (ignoring negative values), or they can be distributed non linearly. As explained here, the ARM architecture uses the 8 least significant bits (256 values) to represent a number and the 4 most significant bits (16 states) to scale up or down this number by a power of 2.
Thanks to this scaling property, the ARM architecture is able to represent a lot of useful large numbers that could otherwise not be represented (even with 16 bits). Unfortunately some of the 4096 states now map to the same number as explained here so only 3073 distinct values can be represented with this approach.
Programmers who want to work with immediates that are not in the set of 3073 valid immediates can use workarounds that require multiple clock cycles and/or memory in order to achieve the desired result.
Conclusion: this is just a different way of distributing the available numbers, not a (magical) way of representing 232 = 4294967296 distinct numbers using 212 = 4096 states!

- 289
- 3
- 16