Here are the easy to confuse four instructions, already in the confusion of the 4 instructions spent a lot of energy, now do a summary,LDR,STR,LDM,STM These four instructions,
For a description of the LDM and STM , see the additional documentation that explains the considerations for these two files for stack operations.
(1)LDR:L means load, The meaning of load should be understood as:load from memory into register. The following statement explains it very clearly:
LDR R1, [R2] ; r1<--[R2]
is to put the value of the contents of the storage unit pointed to by R2 (the value within a memory address), read into the R1 (a register)
(2)STR:S means store,store meaning should be understood as:store from a register into memory. The following statement is clear:
STR R1, [R2] ; R1-->[R2]
is to "save" the contents of the Register R1 to the stored cell (a memory address) pointed to by R2 .
Obviously, these two statements have a feature, that is, register is written in front (left) and memory address is written in the back (right), the direction of data transmission is exactly the opposite.
The following is an introduction to LDM and STM, which is described using the SP, as it is used in practice with more than the SP.
(3)LDM: The meaning ofL is still load, which is the load from memory into register.
Although it seems to be LDR upgrade, but, it is important to note that the direction of operation of this command and LDR is not the same, from left to right to run.
This instruction is the data in the memory stack, the batch assignment to the register, that is, the stack operation;
Where the stack pointer generally corresponds to the SP, note that the SP is the Register R13, the actual use of the memory address in the R13 , but the instruction is not written as [R13],
At the same time, the position of the register and memory address in theLDM instruction has changed relative to the previous two directives, the following example:
ldmfd sp!, {R0, R1, R2} ; Can actually be understood as: Ldmfd [sp]!, {R0, R1, R2}
This means: Copy the data from the 3 contiguous address segments that the SP points to (which should be 3*4=12 bytes (because R0,R1,R2 is 32 bits)) to the R0,R1,R2 3 registers.
( If this place still does not understand, you can refer to my article at the beginning of the link, there are detailed illustrations )
(4)STM: The meaning ofS is still STORE, which is used in pairing with LDM , and its instruction format is similar, that is, different from STR is to write the stack pointer on the left and write the register group to the right.
stmfd sp!, {R0} ; Similarly, the directive can be understood as: Stmfd [sp]!, {R0}
This means: Save the R0 to the stack (the address the SP points to).
Obviously, the two stack operation instructions also have a feature, that is, the Register group is written in the back (right) and the stack pointer is written in front (left),
And actually use the memory address in the stack pointer, which is different from the previous two instructions.
(add: Behind the SP!) , the function is that when the command is executed, the corresponding address value is assigned to the SP, and for the SDM of the routine, the last SP value should be sp+3*4=sp+12)
Of these four instructions, the first two and the next two are actually not much, but the difference is very large, so you can directly distinguish between the two sets of instructions, that there is no link between them, so as to avoid misunderstanding.
The main uses of STM and LDM are field protection, data replication, parameter transfer, etc., with 8 modes, as follows:
Note: The first 4 transports for the data block, and 4 for the stack operation
(1) IA address plus 4 after each transfer--INC after
(2) IB per delivery address plus 4--INC before
(3) address minus 4 for DA after each transfer-DEC after
(4) DB address minus 4 before each transfer-Dec before
(5) FD full decrement stack
(6) FA full increment stack
(7) ED empty decrement stack
(8) EA empty increment stack
The following narration also applies to the empty decrement stack and the empty increment stack.
In the case of a stack operation, it is often wrong to use the LDMFA when the data is ejected when the register is pressed into the stack with STMFD full decrement.
However, FD and FA are only used to indicate what mode the stack is currently operating on (there are four modes in the stack), and FD indicates that the current stack is full of descending stacks.
When the data is in the stack instruction is STMFD, then the data out of the stack of instructions corresponding to the LDMFD, rather than LDMFA.
We can think of this as STMFD equivalent to STMDB,LDMFD equivalent to Stmia
So what is the order of data transfer and the order in which it is in the stack?
Take a look at the result diagram of STMFD Sp!,{r1-r3} (SP points to SP after operation)
SP-------> | r3| | r2| SP'------>| r1|
So Stmfd sp!,{r3,r2,r1} after the execution of the stack order is exactly the same as the above stack order, the actual situation when the two instructions after the execution of the stack data order,
Because the arm compiler automatically converts STMFD sp!,{r3,r2,r1} to the STMFD sp!,{r0-r3} instruction, the arm compiler defaults to the stack by default high register precedence.
Even if you deliberately "schedule" the Register in the Order of Stmfd Sp!,{r3,r2,r1}, and at compile-time the compiler has re-processed it, disrupting the order in which you expect the data to be put into the stack.
Similarly, the order of the data in the stack is exactly the same as Stmdb R0!,{r1-r3} and Stmdb r0!,{r3,r2,r1} instructions.
STMFD SP!,{R1-R3} instruction is ldmfd SP!,{R1-R3} (the Order of R1,R2,R3)
ARM ldr/str, ldm/stm Directive