The instruction “idr ro, [r1, #4]” is an ARM assembly language instruction used on ARM Cortex processors. It stands for “Integer Data Register – Read Only, register 1, shift left by 4 bits”. This instruction reads a 32-bit value from register r1, shifts it left by 4 bit positions, and stores the result in register r0 as a read-only value.
ARM Assembly Language
ARM assembly language is used to directly program ARM processors like the Cortex-M and Cortex-A series. Unlike high level languages like C and C++, assembly language instructions correspond directly to processor instructions. Each statement in ARM assembly translates to one machine code instruction.
Assembly gives programmers complete control over the processor, allowing for optimization and access to special instructions not available in high level languages. However, it can be more difficult to develop in assembly due to its low level nature.
ARM Registers
The ARM processor contains 16 general purpose 32-bit registers named r0 to r15. These registers can be used to store data values and memory addresses. By convention, r13 is used as the stack pointer and r14 is used as the link register for function calls.
The “r” prefix identifies a register operand. So “r1” refers to register 1 which is one of the general purpose registers available.
Data Transfer Instructions
“Idr” stands for “Integer Data Register Load” which belongs to the category of data transfer instructions in the ARM instruction set. These instructions move 32-bit data between registers and memory.
Some other data transfer instructions are:
- Ldr – Load Register
- Str – Store Register
- Ldm – Load Multiple Registers
- Stm – Store Multiple Registers
Read Only Register
The “.ro” suffix sets the destination register (r0 in this case) to read-only access. This means that subsequent instructions cannot modify the value in r0 until the read-only restriction is removed.
Read-only registers are useful to protect important values from being unintentionally changed.
Shift Left by 4 Bits
The “[r1, #4]” operand specifies a shift left by 4 bit positions on the value in r1 before transferring it to r0. Shifting left by n bits is equivalent to multiplying by 2n.
Some key points on the shift operand:
- #4 – Indicates an immediate shift amount of 4 bits.
- Shifting left by 1 bit doubles the value.
- Shifting left by 4 bits multiplies the value by 24 = 16.
- Vacated bits on the right are filled by 0.
Idr ro, [r1, #4] Step-by-Step
To summarize, these are the steps performed by the “idr ro, [r1, #4]” instruction:
- Read the 32-bit value in register r1.
- Shift the value left by 4 bit positions, filling vacant bits with 0.
- Load the shifted result into register r0 as a read-only value.
Some examples:
- If r1 contains the value 0x000000FF, it gets shifted to 0x00000FF0 in r0
- If r1 contains 0x00AABBCC, it gets shifted to 0x0AABBCC0 in r0
Idr Instruction Usage
The idr instruction is useful when you need to load a read-only value derived from a source register. Some cases where it can be used:
- Masking operations – Shift left to create a mask, then AND with r0 to clear selective bits.
- Extracting bitfields – Shift and load a bitfield from a larger value into r0.
- Logical shifts – Shift left/right to quickly multiply/divide by powers of 2.
- Address calculations – Shift and add based on word size to index into arrays.
The read-only register prevents accidental writes to the derived value. The shifted value can also be combined with other data transfer or arithmetic instructions.
Masking Example
ldr r1, =0x00FF0000 ; Load r1 with bitmask idr r0, [r1, #4] ; Shift mask left by 4 bits and r2, r0 ; AND to mask bits in r2
Bitfield Extraction Example
ldr r1, [addr] ; Read value from memory idr r0, [r1, #16] ; Extract bits 16-31 of r1 into r0
Idr Instruction Format
The full syntax of the idr instruction is: idr{<c>}{<q>} <Rd>, [<Rm> {, #<shift>}]
- c – Optional condition code like eq, ne, gt
- q – Optional assembler qualifier like .w to specify word-sized offset
- Rd – Destination register
- Rm – Source register containing value to be shifted
- shift – Optional shift amount from 0 to 31
Some examples: idrne r3, [r5, #8] ; Shift r5 left 8 bits if condition is NOT equal idrgt r0, [r1, LSL #3] ; Logical shift left r1 by 3 if greater than
Summary
The “idr r0, [r1, #4]” instruction loads register r0 with a read-only, shifted version of r1’s value. It shifts r1 left by 4 bits before transferring the result to r0.
This instruction is useful for masking, isolating bitfields, and preparing constants needed by other instructions. The idr gives programmers direct access to the underlying shift and data transfer capabilities of the ARM processor.