home | bit manipulation | data manipulation | addressing | loops | conditional execution/flags | about the author
useful documents | exercises | ARMulator | forum | links | c/c++ introduction | contact us | other websites by the author

Addressing

As has been previously described it is possible to assign an immediate value to a register using the MOV instruction, but it is not yet clear how to transfer data between memory and registers. The LDR instruction which stands for 'LOAD REGISTER' can be used to transfer a data word (i.e 32-bits) from memory to registers. It takes the following format:

LDR(cc) Rd, [op2] R0 = mem32[R1]

where mem32[R1] is a word memory address of value R1, which is known as the base address. N.B R1 must be divisible by 4 because LDR is a word transfer. see diagram below.

The opposite of LDR is STR which stands for 'STORE REGISTER', this has the effect of transfering the current value held by a register to a memory location without changing either the base address register or the data register. Again this is a word transfer. STR takes the following format:

STR(cc) Rd, [op2] Here the value held in Rd will be stored in the memory value indicated by op2. see diagram.

Examples

MOV R1, #10                      ;R1 = 10
MOV R2, #&ABCDEF      ;R2=#ABCDEF;
STR R1, [R2]                       ;mem32[R2]=R1
LDR R3, [R2]                      ;R3=mem32[R2]


Quite often in assembly language programs you are required to read a large block of data from memory, most often a part of the solution to this problem is by reading successive words from memory. To do this a loop is created in which a memory read or LDR instruction is present so that each time the loop executes another memory location is read:

MOV R3, #10;
MOV R1, #&0
loop LDR R2, [R1]
ADD R1, R1, #4
SUB R3, R3, #1
;some useful code
;end of loop

As you can hopefully see R1 is first set to hex 0, R2 is then made equal to the value held at address hex R1. R1 is then incremented by 4 which moves it onto the next word, as previously explained. Here R3 has been used as the loop counter, it is decremented by 1 every loop execution, when it reaches 0 the loop will terminate. To simplify this procedure post-indexed addressing mode with auto-indexing can be used, this allows the base register to be updated (changed) after the memory read (LDR) has been executed. An example follows:

MOV R3, #10;
MOV R1, #&0
loop LDR R2, [R1], #4
SUB R3, R3, #1
;some useful code
;end of loop

So now the effective address is R1 + 4, it is important to note that R1 is updated after the execution of LDR, and that it is permanently changed.
A number of variations exist for this type of operation, they are summarized below.

assembly code notes name
LDR R0,[R1] This is the simplest method of reading from memory, with no indexing. register-indirect addressing.
LDR R0, [R1], #offset This indexing method updates the base register (R1) after the LDR instruction has been executed post-indexed, auto-indexing
LDR R0, [R1 #offset] Here the base register is not updated at all, an offset is simply added to the base register just for the LDR pre-indexed
LDR R0, [R1,#offset ]! This is similar to post-indexed, auto-indexing except here the base address is updated before the LDR instruction is executed. pre-indexed, auto-indexing
LDR R0, [R1, r2, lsl #xyz] register register-indexed addressing, with scaling

LOAD/STORE SINGLE BYTE

However if you want to read from or write to memory less than a 32-bit word, it is possible to read/write a single byte (4-bits). To do this an LDRB or STRB can be used, it easy to remember this because the 'B' stands for BYTE. Both are used in the same way as LDR/STR the only difference being they dont require an address divisible by 4. An example follows:

LOAD/STORE Multiple

Another way to save multiple registers into memory simultaneously (to the user) is to use the STM or LDM which stands for 'STORE MULTIPLE' and 'LOAD MULTIPLE' respectively. This allows the programmer to save to memory multiple registers in successive memory locations. It takes the following form:
STM R0!, {R1, R3-R6}
Here R0 is the base register which defines the first address in memory. After which the addresses are either decreased or increased, remember that this is word addressing so each register occupies one line of memory. The user is able to choose whether the memory addresses decrease (decrement )or increase (increment) to do this two letters are appended to the end of the STM or LDM:
IA -Increment After STMIA / LDMIA
IB -Increment Before STMIB / LDMIB
DA -Decrement After STMDA / LDMDA
DB -Decrement Before STMDB / LDMDB

Increment After means that the base address will be updated AFTER the register has either been read into or from memory. Increment before means that the base address will be updated BEFORE the register has either been read into or from memory. The corresponding DECREMENT instructions operate in the same way but decrement the base address instead.

The Stack

Going into a loop...
Click Here for a large range of ARM assembly books at low prices!

ARM Assembly Language - an Introduction by J. R. Gibson

ARM Assembly by William Hohl