arm 寄存器装载和存储

ARM 137浏览

传送单一数据

1.SP(R13) LR(R14)PC(R15)

2.lr(r14)的作用问题,这个lr一般来说有两个作用:
1》.当使用bl或者blx跳转到子过程的时候,r14保存了返回地址,可以在调用过程结尾恢复。
2》.异常中断发生时,这个异常模式特定的物理R14被设置成该异常模式将要返回的地址。

另外注意pc,在调试的时候显示的是当前指令地址,而用mov lr,pc的时候lr保存的是此指令向后数两条指令的地址,大家可以试一下用mov pc,pc,结果得到的是跳转两条指令,这个原因是由于arm的流水线造成的,预取两条指令的结果.

使用单一数据传送指令(STR 和 LDR)来装载和存储单一字节或字的数据从/到内存。寻址是非常灵活的。

首先让我们查看指令格式:

LDR{条件}    Rd, <地址>    -------------------> 内存到寄存器
STR{条件}    Rd, <地址>    -------------------> 寄存器到内存

内存的表示方式有:立即数,寄存器,或寄存器加偏移,立即数:内存的物理位置,前面加个#,如0x56000050
寄存器,加个[],如[r1],偏移的话[r1,r2],或者[r1,#4],[r1,LSL #4]等,都差不多,就是把寄存器里的数当成地址

下面指令请参考传送格式:

LDR{条件}B   Rd, <地址>
STR{条件}B   Rd, <地址>







LDR伪指令的形式是“LDR Rn,=expr”。作用是装在一个32bit常数和一个地址到寄存器。 





下面举一个例子来说明它的用法。 

LDR       R1,=COUNT 
MOV       R0,#0 
STR     R0,[R1]













单一数据传送格式参考:

xxxx010P UBWLnnnn ddddoooo oooooooo  Immediate form
xxxx011P UBWLnnnn ddddcccc ctt0mmmm  Register form

典型的汇编语法:

        LDR  Rd, [Rn, Rm, ASL#1]!
        STR  Rd, [Rn],#2
        LDRT Rd, [Rn]
        LDRB Rd, [Rn]

这些指令装载/存储内存的一个字从/到一个寄存器。在指定地址时使用的第一个寄存器在术语上叫做基址寄存器。

如果设置了 L 位,则进行装载,否则进行存储。

如果设置了 P 位,则使用预先变址寻址,否则使用过后变址寻址。

如果设置了 U 位,则给出的偏移量被加到基址寄存器上 - 否则从中减去偏移量。

如果设置了 B 位,传送内存的一个字节,否则传送一个字。这在汇编器中表示为给根助记符的加上后缀‘B’。

W 位的解释依赖于使用的地址模式:

  • 对于预先变址寻址,设置 W 位强制把用做地址转换的最终地址写回基址寄存器中。(示例,传送的副作用是 Rn := Rn +/- offset。这在汇编器中表示为给指令加上后缀 ‘!’。)
  • 对于过后变址寻址,地址总是写回,设置 W 位指示在进行传送之前强制地址转换。这在汇编器中表示为给指令加上后缀‘T’。

地址转换导致芯片告知内存系统这是一个用户模式传送,而不管此时芯片是处于用户模式中还是处于特权模式中。这是有用的,示例在写模拟器的时候: 如果一个用户模式程序一个内存区域执行了一个  STF 指令,而用户模式代码不可以写这个内存区域。如果由一个 FPA 来指令它,它将异常终止。如果由一个 FPE 来执行它,它也应该异常终止。但是 FPE 运行在一个特权模式下,所以如果它使用普通存储指令,则它不会异常终止。为了使异常终止正确工作,在一个特权模式调用它时使用 STRT 替代普通存储指令,使其如同调用自用户模式。

如果使用这个指令的立即数形式,o 字段给出一个 12-bit 偏移量。如果使用了寄存器形式,则按对数据处理指令那样解码它,限制是不允许使用寄存器指令移位量。

如果 R15 被用做 Rd,不修改 PSR。PC 不应该被用在 Op2 中。

其他限制:

  • 在基址寄存器是 PC 的时候不要使用写回或过后变址。
  • 不要使用 PC 作为给 LDRB 或 STRB 的 Rd。
  • 在使用带有寄存器偏移量的过后变址时,不要让 Rn 和 Rm 是同一个寄存器(这样做导致不可能从异常终止中恢复)。

装载使用 1S + 1N + 1I + (1S + 1N 如果改变了 PC)个周期,而存储使用 2N 个周期。