如何保存一组寄存器,以后再恢复?

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

Arm System Developers Guide 一书中的以下示例显示了指令前的 STM 递增和指令后的 LDM 递减。

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

STMIB指令将值7、8、9存入内存。然后我们破坏寄存器 r1 到 r3。 LDMDA 重新加载原始值并恢复基指针 r0。

但是,r1,r2,r3的内存已经被1,2,3覆盖了。那么,以前的值是如何恢复的。它在哪里保存旧值?

LDM/STM(在您的示例中为r0)的第一个操作数是基址寄存器。该寄存器保存寄存器列表中的值将存储在内存中的地址。

因此,例如,当您 STMIB r0!,{r1-r3}r0==0x9000 时,您会将 r1 的值存储在地址 0x9004r20x9008r30x900C。请注意,none 的值存储在地址 0x9000,因为您使用了 IB,这意味着 在 (storing/reading)[= 之前​​增加(地址) 44=].
! 表示最终地址 (0x900C) 将写回到 r0.

然后,当您执行 LDMDA r0!,{r1-r3} 时,您会从 r0==0x900C 开始。 DA 表示 之后递减,因此地址将在我们加载每个寄存器后递减,并且由于最低寄存器总是被传输 to/from 我们开始的最低内存地址通过从地址 0x900C 加载 r3,然后从 0x9008 加载 r2,最后从 0x9004 加载 r1