Syntax:
op{cond}mode Rn{!}, reglist{^}
where:
op is either LDM or STM.
cond is an optional condition code (see Conditional execution on page 4-4).
mode is any one of the following:
IA increment address after each transfer
IB increment address before each transfer
DA decrement address after each transfer
DB decrement address before each transfer
FD full descending stack
ED empty descending stack
FA full ascending stack
EA empty ascending stack.
Rn is the base register, the ARM register containing the initial address for the
transfer. Rn must not be r15.
! is an optional suffix. If ! is present, the final address is written back into Rn.
reglist is a list of registers to be loaded or stored, enclosed in braces. It can
contain register ranges. It must be comma separated if it contains more
than one register or register range (see Examples on page 4-19).
^ is an optional suffix. You must not use it in User mode or System mode.
It has two purposes:
◆ If op is LDM and reglist contains the pc (r15), in addition to the
normal multiple register transfer, the SPSR is copied into the CPSR.
This is for returning from exception handlers. Use this only from
exception modes.
◆ Otherwise, data is transferred into or out of the User mode registers
instead of the current mode registers.

cond: 指令执行的条件码
P : 前/后变址
U : 增/减
S : 对应指令中的“^”符号
W : 回写
L : 区别加载(1)或存储(0)
Rn : 基址寄存器
Register list : 寄存器列表
——LDMFD、STMFD标识对满递减栈的多寄存器装载、存储,其等价于LDMIA(Increment After)、STMDB(Decrement Before)。
3、小结: 这是在中断程序中常用的入栈出栈指令,图解它们的入栈、出栈流程如下:STMFD SP!, {R0-R3, R12, LR}
…… …… LDMFD SP!, {R0-R3, R12, PC}^

范例:
AREA Tblock, CODE, READONLY ; name this block of code
num EQU 20 ; Set number of words to be copied
ENTRY ; mark first instruction to execute
CODE32 ; Subsequent instructions are ARM header
MOV sp, #0x400 ; set up user_mode stack pointer (r13)
ADR r0, start + 1 ; Processor starts in ARM state,
BX r0 ; so small ARM code header used
; to call Thumb main program.
CODE16 ; Subsequent instructions are Thumb.
start
LDR r0, =src ; r0 = pointer to source block
LDR r1, =dst ; r1 = pointer to destination block
MOV r2, #num ; r2 = number of words to copy
blockcopy
LSR r3,r2, #2 ; number of four word multiples
BEQ copywords ; less than four words to move ?
PUSH {r4-r7} ; save some working registers
quadcopy
LDMIA r0!, {r4-r7} ; load 4 words from the source
STMIA r1!, {r4-r7} ; and put them at the destination
SUB r3, #1 ; decrement the counter
BNE quadcopy ; ... copy more
POP {r4-r7} ; don't need these now - restore originals
copywords
MOV r3, #3 ; bottom two bits represent number...
AND r2, r3 ; ...of odd words left to copy
BEQ stop ; No words left to copy ?
wordcopy
LDMIA r0!, {r3} ; a word from the source
STMIA r1!, {r3} ; store a word to the destination
SUB r2, #1 ; decrement the counter
BNE wordcopy ; ... copy more
stop
MOV r0, #0x18 ; angel_SWIreason_ReportException
LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit
SWI 0xAB ; Thumb semihosting SWI
AREA BlockData, DATA, READWRITE
src DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4
dst DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
END