如何保存一组寄存器并在以后恢复?

时间:2015-01-27 06:09:05

标签: assembly arm cpu-registers instruction-set

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覆盖。然后,如何恢复以前的值。它在哪里保存旧值?

1 个答案:

答案 0 :(得分:0)

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

因此,例如,当STMIB r0!,{r1-r3}r0==0x9000 r1时,您将0x9004的值存储在地址r20x9008处{ {1}}和r3 0x900C。请注意,没有任何值存储在地址0x9000,因为您使用了IB,这意味着在(存储/读取)之前增加(地址)。
!表示最终地址(0x900C)将被写回r0

然后,当您执行LDMDA r0!,{r1-r3}时,您将从r0==0x900C开始。 DA表示之后递减,因此地址将在我们加载的每个寄存器之后递减,并且由于最低的寄存器总是从最低的内存地址转移到我们开始加载{{1来自地址r3,然后来自0x900C的{​​{1}},最后来自r2的{​​{1}}。