the benefits and capabilities of the load and store multiple
instructions;
types of stacks supported directly by load and store multiple.
Multiple vs single transfers
The Load and Store Multiple instructions provide a way to efficiently move
the contents of several registers to and from memory. The advantages of
using a single load or store multiple instruction over a series of load or
store single instructions are:
Smaller code size;
On Von Neumann architectures such as all ARMs up to the ARM6 family,
there is only a single instruction fetch overhead, rather than many
instruction fetches.
On Von Neumann architectures, only one register write back cycle is
required for a load multiple, as opposed to one for every load single;
On uncached ARM processors, the first word of data transfered by a
load or store multiple will always be a non-sequential memory cycle, but
all subsequent words transferred can be sequential (faster) memory cycles.
The register list
The registers the load and store multiple instructions transfer are
encoded into the instruction by one bit for each of the registers R0 to
R15. A set bit indicates the register will be transferred, and a clear
bit indicates that it will not be transferred. Thus it is possible to
transfer any subset of the registers in a single instruction.
The way the subset of registers to be transferred is specified is simply
by listing those registers which are to be transferred in curly brackets
eg.
{R1, R4-R6, R8, R10}
Increment / Decrement, Before / After
The base address for the transfer can either be incremented or decremented
between register transfers, and this can happen either before or after
each register transfer. eg.
STMIA R10, {R1, R3-R5, R8}
The suffix IA could also have been IB, DA or DB, where I indicates
increment, D decrement, A after and B before.
Base register writeback
In the last instruction, although the address of the transfer was changed
after each transfer, the base register was not updated at any point.
Register writeback can be specified so that the base register is updated.
Clearly the base register will change by the same amount whether "before"
or "after" is selected. An example of a load multiple using base
writeback is:
LDMDB R11!, {R9, R4-R7}
Note
In all cases the lowest numbered register is transferred to or from the
lowest memory address, and the highest numbered register to or from the
highest address. [The order in which the registers are listed in the
register list makes no difference. Also, the ARM always performs
sequential memory accesses in increasing memory address order. Therefore
'decrementing' transfers actually perform a subtraction first and then
increment the transfer address register by register].
Stack notation
Since the load and store multiple instructions have the facility to update
the base register (which for stack operations can be the stack pointer),
these instructions provide single instruction push and pop operations for
any number of registers. Load multiple being pop, and store multiple
being push.
There are several types of stack which the Load and Store Multiple
Instructions can be used with:
Ascending or descending stacks. ie. the stack grows up memory or down
memory. [Sometimes a pair of stacks, one of which grows up memory and one
of which grows downwards are used - thus choosing the direction is not
always just a matter of taste].
Empty or Full stacks. The stack pointer can either point to the top
item in the stack (a full stack), or the next free space on the stack (an
empty stack).
As stated above, pop and push operations for these stacks can be
implemented directly by load and store multiple instructions. To make it
easier for the programmer special stack sufficies can be added to the LDM
and STM instructions (as an alternative to Increment / Decrement and
Before / After sufficies) as follows:
STMFA R10!, {R0-R5} ; Push R0-R5 onto a Full Ascending Stack
LDMFA R10!, {R0-R5} ; Pop R0-R5 from a Full Ascending Stack
STMFD R10!, {R0-R5} ; Push R0-R5 onto a Full Descending Stack
LDMFD R10!, {R0-R5} ; Pop R0-R5 from a Full Descending Stack
STMEA R10!, {R0-R5} ; Push R0-R5 onto an Empty Ascending Stack
LDMEA R10!, {R0-R5} ; Pop R0-R5 from an Empty Ascending Stack
STMED R10!, {R0-R5} ; Push R0-R5 onto an Empty Descending Stack
LDMED R10!, {R0-R5} ; Pop R0-R5 from an Empty Descending Stack