EmbeddedRelated.com
Forums
The 2026 Embedded Online Conference

Question about ARM instruction: STMIA / STMEA

Started by Robert Willy August 6, 2015
Hi,

When I read ARM Thumb2 instruction manual, I find a problem on 
STMIA / STMEA.

It said: "Store Multiple Increment After (Store Multiple Empty Ascending)
 stores multiple registers to consecutive memory locations using an address
 from a base register."

Does that mean STMIA is equivalent to STMEA?

Then, when I try to find the answer online, I have more questions on this
topic. Below the dot line is from Keil website. Although it gives more
explanation, I don't understand it, especially Table 4.5 and 4.6.

For example, on Table 4.5, there is one row has content:

FD (Full Descending stack)	DB (Decrement Before)	IA (Increment After)

I don't see the relationship between 'DB' and 'IA'. Could you explain it
to me a little more?


Thanks in advance.



...............
http://www.keil.com/support/man/docs/armasm/armasm_dom1359731152499.htm

4.15 Stack implementation using LDM and STM
You can use the LDM and STM instructions to implement pop and push operations respectively. You use a suffix to indicate the stack type.

The load and store multiple instructions can update the base register. For stack operations, the base register is usually the stack pointer, SP. This means that you can use these instructions to implement push and pop operations for any number of registers in a single instruction.
The load and store multiple instructions can be used with several types of stack:
Descending or ascending
The stack grows downwards, starting with a high address and progressing to a lower one (a descending stack), or upwards, starting from a low address and progressing to a higher address (an ascending stack).
Full or empty
The stack pointer can either point to the last item in the stack (a full stack), or the next free space on the stack (an empty stack).
To make it easier for the programmer, stack-oriented suffixes can be used instead of the increment or decrement, and before or after suffixes. The following table shows the stack-oriented suffixes and their equivalent addressing mode suffixes for load and store instructions:
Table 4-5 Stack-oriented suffixes and equivalent addressing mode suffixes

Stack-oriented suffix	For store or push instructions	For load or pop instructions
FD (Full Descending stack)	DB (Decrement Before)	IA (Increment After)
FA (Full Ascending stack)	IB (Increment Before)	DA (Decrement After)
ED (Empty Descending stack)	DA (Decrement After)	IB (Increment Before)
EA (Empty Ascending stack)	IA (Increment After)	DB (Decrement Before)
The following table shows the load and store multiple instructions with the stack-oriented suffixes for the various stack types:
Table 4-6 Suffixes for load and store multiple instructions

Stack type	Store	Load
Full descending	STMFD (STMDB, Decrement Before)	LDMFD (LDM, increment after)
Full ascending	STMFA (STMIB, Increment Before)	LDMFA (LDMDA, Decrement After)
Empty descending	STMED (STMDA, Decrement After)	LDMED (LDMIB, Increment Before)
Empty ascending	STMEA (STM, increment after)	LDMEA (LDMDB, Decrement Before)
For example:
    STMFD    sp!, {r0-r5}  ; Push onto a Full Descending Stack
    LDMFD    sp!, {r0-r5}  ; Pop from a Full Descending Stack
On 2015-08-06, Robert Willy <rxjwg98@gmail.com> wrote:
> Hi, > > When I read ARM Thumb2 instruction manual, I find a problem on > STMIA / STMEA. > > It said: "Store Multiple Increment After (Store Multiple Empty Ascending) > stores multiple registers to consecutive memory locations using an address > from a base register." > > Does that mean STMIA is equivalent to STMEA? >
I don't use ascending stacks, or the *EA instruction variants, so you need to check this yourself with objdump (or the equivalent tool in your toolchain) but I suspect you will find they generate the same opcode.
> Then, when I try to find the answer online, I have more questions on this > topic. Below the dot line is from Keil website. Although it gives more > explanation, I don't understand it, especially Table 4.5 and 4.6. > > For example, on Table 4.5, there is one row has content: > > FD (Full Descending stack) DB (Decrement Before) IA (Increment After) > > I don't see the relationship between 'DB' and 'IA'. Could you explain it > to me a little more? >
You use the first one (STMDB) to push onto the stack and you use the second one (LDMIA) to pop from the stack. Read the section you quoted again, but thinking about how the address of the next available slot on the stack varies depending depending on the stack model in use and then you will realise they complement each other. If it helps, draw out on paper how the stack contents (and stack pointer) change after each instruction variant and think about how this allows you to store data to, and recover data from, the stack. Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world
Simon Clubley <clubley@remove_me.eisner.decus.org-earth.ufp> wrote:
> On 2015-08-06, Robert Willy <rxjwg98@gmail.com> wrote: > > When I read ARM Thumb2 instruction manual, I find a problem on > > STMIA / STMEA. > > > > It said: "Store Multiple Increment After (Store Multiple Empty > > Ascending) stores multiple registers to consecutive memory locations > > using an address from a base register." > > > > Does that mean STMIA is equivalent to STMEA? > > I don't use ascending stacks, or the *EA instruction variants, so you > need to check this yourself with objdump (or the equivalent tool in > your toolchain) but I suspect you will find they generate the same opcode.
They will, it's simply assembler sugar: STMEA = STMIA LDMEA = LDMDB STMFD = STMDB LDMFD = LDMIA and so on. It's just two different notations, one for stacks (where you go 'forwards' and 'backwards') and one for normal loads/stores (where there's usually only 'forwards' - most data structures start at a low address and grow towards a higher address). Theo
On Thu, 06 Aug 2015 15:42:07 -0700, Robert Willy wrote:

> When I read ARM Thumb2 instruction manual, I find a problem on > STMIA / STMEA. > > It said: "Store Multiple Increment After (Store Multiple Empty Ascending) > stores multiple registers to consecutive memory locations using an address > from a base register." > > Does that mean STMIA is equivalent to STMEA?
Yes.
> Then, when I try to find the answer online, I have more questions on this > topic. Below the dot line is from Keil website. Although it gives more > explanation, I don't understand it, especially Table 4.5 and 4.6. > > For example, on Table 4.5, there is one row has content: > > FD (Full Descending stack) DB (Decrement Before) IA (Increment After) > > I don't see the relationship between 'DB' and 'IA'. Could you explain it > to me a little more?
"EA" means that the stack is a) "empty", meaning that the stack pointer points to the first word beyond the end of the stack (i.e. where the next "pushed" word will be stored), and b) "ascending", meaning that the stack grows upward in memory, i.e. pushing increases the stack pointer while popping decreases it. So to push a word onto an empty+ascending stack, you store the word at the current stack pointer then increment the stack pointer (increment after = IA). To pop a word from an empty+ascending stack you first decrement the stack pointer (so that it points to the last word on the stack rather than the space after it) then read the word it now points to (decrement before = DB). To summarise: STMEA = STMIA, LDMEA = LDMDB. The Increment/Decrement Before/After syntax describes the operation in terms of what happens to the register and when (this is the conventional pre/post-increment/decrement terminology). It's more appropriate if you aren't manipulating a stack. The Empty/Full Ascending/Descending syntax describes the nature of the stack (on the assumption that you are actually dealing with a stack). With the former, load and store operations are asymmetric (or more accurately, anti-symmetric). Whichever suffixes are used for the store, the opposite suffixes must be used for the load, e.g. STMIA<=>LDMDB. With the latter, load and store always use the same suffix, e.g. STMEA<=>LDMEA. This is all syntactic sugar. The LDM/STM opcode format has a flag for Increment (set) or Decrement (clear) and another for Before (set) or After (clear). The assembler takes care of converting either syntax to the appropriate flags. Load Incr Before Opcode 1 Opcode 2 0 0 0 STMDA STMED 0 0 1 STMDB STMFD 0 1 0 STMIA STMEA 0 1 1 STMIB STMFA 1 0 0 LDMDA LDMFA 1 0 1 LDMDB LDMEA 1 1 0 LDMIA LDMFD 1 1 1 LDMIB LDMED
On Thursday, August 6, 2015 at 3:42:12 PM UTC-7, Robert Willy wrote:
> Hi, > > When I read ARM Thumb2 instruction manual, I find a problem on > STMIA / STMEA. > > It said: "Store Multiple Increment After (Store Multiple Empty Ascending) > stores multiple registers to consecutive memory locations using an address > from a base register." > > Does that mean STMIA is equivalent to STMEA? > > Then, when I try to find the answer online, I have more questions on this > topic. Below the dot line is from Keil website. Although it gives more > explanation, I don't understand it, especially Table 4.5 and 4.6. > > For example, on Table 4.5, there is one row has content: > > FD (Full Descending stack) DB (Decrement Before) IA (Increment After) > > I don't see the relationship between 'DB' and 'IA'. Could you explain it > to me a little more? > > > Thanks in advance. > > > > ............... > http://www.keil.com/support/man/docs/armasm/armasm_dom1359731152499.htm > > 4.15 Stack implementation using LDM and STM > You can use the LDM and STM instructions to implement pop and push operations respectively. You use a suffix to indicate the stack type. > > The load and store multiple instructions can update the base register. For stack operations, the base register is usually the stack pointer, SP. This means that you can use these instructions to implement push and pop operations for any number of registers in a single instruction. > The load and store multiple instructions can be used with several types of stack: > Descending or ascending > The stack grows downwards, starting with a high address and progressing to a lower one (a descending stack), or upwards, starting from a low address and progressing to a higher address (an ascending stack). > Full or empty > The stack pointer can either point to the last item in the stack (a full stack), or the next free space on the stack (an empty stack). > To make it easier for the programmer, stack-oriented suffixes can be used instead of the increment or decrement, and before or after suffixes. The following table shows the stack-oriented suffixes and their equivalent addressing mode suffixes for load and store instructions: > Table 4-5 Stack-oriented suffixes and equivalent addressing mode suffixes > > Stack-oriented suffix For store or push instructions For load or pop instructions > FD (Full Descending stack) DB (Decrement Before) IA (Increment After) > FA (Full Ascending stack) IB (Increment Before) DA (Decrement After) > ED (Empty Descending stack) DA (Decrement After) IB (Increment Before) > EA (Empty Ascending stack) IA (Increment After) DB (Decrement Before) > The following table shows the load and store multiple instructions with the stack-oriented suffixes for the various stack types: > Table 4-6 Suffixes for load and store multiple instructions > > Stack type Store Load > Full descending STMFD (STMDB, Decrement Before) LDMFD (LDM, increment after) > Full ascending STMFA (STMIB, Increment Before) LDMFA (LDMDA, Decrement After) > Empty descending STMED (STMDA, Decrement After) LDMED (LDMIB, Increment Before) > Empty ascending STMEA (STM, increment after) LDMEA (LDMDB, Decrement Before) > For example: > STMFD sp!, {r0-r5} ; Push onto a Full Descending Stack > LDMFD sp!, {r0-r5} ; Pop from a Full Descending Stack
After several trials, I find that the original STR type stack operations: PUSH {LR} SUB SP, SP, #44 STR V1, [SP, #28] STR V2, [SP, #24] STR V3, [SP, #20] STR V4, [SP, #16] STR A4, [SP, #12] STR A3, [SP, #8] STR A2, [SP, #4] STR A1, [SP, #0] can be replaced as: PUSH {LR} SUB SP, SP, #44 STR A4, [SP, #12] STR A3, [SP, #8] STR A2, [SP, #4] STR A1, [SP, #0] ADD A4, SP, #28+4 STMFD A4!, {V1-V4} LDR A4, [SP, #12] That is, the original offset #28 is substituted as #32. The pop stack part LDR LDR V4, [SP, #16] LDR V3, [SP, #20] LDR V2, [SP, #24] LDR V1, [SP, #28] ADD SP, SP, #44 is substituted as: ADD A4, SP, #16 LDMFD A4!, {V1-V4} ADD SP, SP, #44 Number #16 is the same. The compiler makes the SP pointer to the full position, increasing to the small address direction with more data pushed in. Although it works as the STR/LDR instructions, I have not figured out why it needs #4 more in the push operation yet. Thanks for your views.
On 8/8/15 6:39 PM, Robert Willy wrote:
> > Although it works as the STR/LDR instructions, I have not figured out why > it needs #4 more in the push operation yet. > > Thanks for your views. >
Because STMFD assumes that the stack pointer is pointing to an 'occupied' (i.e. 'Full') location, so it is decremented first before the 1st store, thus you need to computer the stack frame location one element farther than the first item.
The 2026 Embedded Online Conference