# Data Movement Instructions

## Addressing Modes

### Register-Indirect addressing

It is perhaps the simplest of ARM's addressing modes.

Register-indirect addressing in action

To load a value from memory into a register using register-indirect addressing, we use a second register, known as the base register. This base register holds the actual memory address that the program is interested in. The LDR instruction inspects the base register, interprets its value as the memory address, fetches the value stored at that memory location, and then loads it into a destination register.

; r0 is the destination register, r1 is the base register

To store a value to memory from a register using register-indirect addressing, a base register is again employed to hold the actual memory address. The STR instruction inspects the base register, interprets its value as a memory address location, and places the value held in the source register into the memory location.

; r0 is the source register, r1 is the base register

### Pre-indexed Addressing

The pre-indexed addressing mode provides a means of simplifying the process be eliminating the ADD instructions.

;the memory location whose address is the value of r1 + 4

In pre-indexed addressing, the base address register (r1 and r2 in the example) are not modified. Occasionally it is useful to update the base address register such that it points to the new address. This is **pre-indexed addressing with auto-indexing**:

; Then, increment r1, such that r1 := r1 +4

The "!" suffix on the effective address indicates that the base register should be incremented after the data transfer.

### Post-indexed Addressing

A next addressing mode is **post-indexed addressing**, which is always auto-indexing. In this mode, the base address stored in the base register is used directly as the effective address, and it is then auto-indexed to point to the next memory location.

STR r0, [r2], #4 ; store value in r0 to memory location pointed to by r2. Increment r2

## Byte Load and Store

The LDR and STR instructions transfer full words, not individual bytes. The ARM can transfer bytes using the LDRB and STRB instructions.

STRB r0, [r1]; store the byte held in r0 into the memory location pointed to by r1

- The byte chosen for LDRB transfer depends on the memory address. If the address is word aligned, bits 0 to 7 are loaded into the destination register. If the address is word aligned plus one byte, bits 8 to 15 are loaded into the destination register and so on. The chosen bits are loaded into the bottom 8 bits of the destination register and all other bits are set to zero.
- In STRB transfer, the bottom 8 bits of the source register are repeated across the entire word as it is sent over the data bus. It is the responsibility of the external memory hardware to ensure that the correct byte is updated.

## Logical Shift Operations

ARM has two logical shift operations, namely LSL (Logical Shift Left) and LSR (Logical Shift Right).

LSL is a logical shift *left* by 0 to 31 places. The vacated bits at the least significant end of the word are filled with zeros.

Logical Shift Left

LSR is a logical shift *right* by 0 to 31 places. The vacated bits at the most significant end of the word are filled with zeros.

Logical Shift Right

Consider the following ARM instruction with r1 = 3 and r2 = 5

Now try the same instruction with a LSL operand, say LSL #3 (logical shift left 3 places which is equivalent to multiplying by 8 (2^3)):

## Arithmetic Shift Operations

ARM has two arithmetic shift operations, namely ASL (Arithmetic Shift Left) and ASR (Arithmetic Shift Right).

ASL is an arithmetic shift *left* by 0 to 31 places. The vacated bits at the least significant end of the word are filled with zeros. It is identical to LSL. In code terms, it is written in the same syntactic form:

MOV r0, r1, ASL r2 ; shift value in r1 by number of places given in r2 and fill in vacant

; slots with 0's

### Arithmetic Shift Left

### Arithmetic Shift Right

ASR is an arithmetic shift *right* by 0 to 32 places. The vacated bits at the most significant end of the word are filled with zeros if the original value (the source operand) was positive. The vacated bits are filled with ones if the original value was negative. This is known as "sign extending" because the most significant bit of the original value is the sign bit for 2's complement numbers, i.e. 0 for positive and 1 for negative numbers. Arithmetic shifting therefore preserves the sign of numbers.

;with copies of original most significant bit

MOV r0, r1, ASR r2 ; shift value in r1 right by number of places given in r2 fill

; in vacant bits with copies of original most significant bit

#### Case-I Arithmetic Shift Right Positive Value

#### Case-II Arithmetic Shift Right Negative Value

## Rotate Operations

The ARM processor has two rotate operations, ROR (Rotate Right) and RRX (Rotate Right with Extend).

ROR behaves much like LSR in that bits are moved between 0 and 32 places to the right. However, whereas the rightmost bits in a LSR operation fall off the register, in a ROR operation, these bits are used to fill the vacated slots at the most significant end of the register. In this way the bits "rotate". If the degree of the rotation is 32 places, then the output is identical to the input as all the bits will have returned to their original location.

ROR can be used with a literal or by sourcing the rotation from a register.

MOV r2, r0, ROR r1 ; rotate r0 by value of places in r1 and put result in r2

**Rotation**

RRX is a ROR operation with a crucial difference. It rotates the number to the right by one place but the original bit 31 is filled by the value of the Carry flag and the original bit 0 is moved into the Carry flag. This allows a 33-bit rotation by using both the register and the carry flag.

Rotation Right extended one place

## References

- WikiNote Founation
- www-mdp.eng.cam.ac.uk