How to save a group of registers and restore them later?

0

The following example from the book Arm System Developers Guide shows an STM increment before instruction followed by an LDM decrement after instruction.

PRE r0 = 0x00009000
r1 = 0x00000009
r2 = 0x00000008
r3 = 0x00000007
STMIB r0!, {r1-r3}
MOV r1, #1
MOV r2, #2
MOV r3, #3

PRE(2) r0 = 0x0000900c
r1 = 0x00000001
r2 = 0x00000002
r3 = 0x00000003
LDMDA r0!, {r1-r3}
POST r0 = 0x00009000
r1 = 0x00000009
r2 = 0x00000008
r3 = 0x00000007

The STMIB instruction stores the values 7, 8, 9 to memory. We then corrupt register r1 to r3. The LDMDA reloads the original values and restores the base pointer r0.

But, the memory of r1, r2, r3 has been overwritten by 1,2,3. Then, how are the previous values restored. Where does it saves the old values?

assembly
arm
cpu-registers
instruction-set
asked on Stack Overflow Jan 27, 2015 by manav m-n • edited Jan 27, 2015 by artless noise

1 Answer

0

The first operand of LDM/STM (r0 in your examples) is the base register. That register holds the address in memory where the values in the register list will be stored.

So, for example, when you STMIB r0!,{r1-r3} with r0==0x9000 you'll store the value of r1 at address 0x9004, r2 at 0x9008, and r3 at 0x900C. Note that none of the values are stored at address 0x9000, because you used IB which means increment (the address) before (storing/reading).
The ! means that the final address (0x900C) will get written back to r0.

Then, when you do the LDMDA r0!,{r1-r3} you start out with r0==0x900C. DA means decrement after, so the address will be decremented after each register we load, and since the lowest register always gets transferred to/from the lowest memory address we start by loading r3 from address 0x900C, then r2 from 0x9008, and finally r1 from 0x9004.

answered on Stack Overflow Jan 27, 2015 by Michael

User contributions licensed under CC BY-SA 3.0