• 之前说过,ARM CPU访问内存或者外设寄存器都是一样的
      • image.png
    • 对于编写的程序来说,无论是访问内存还是访问外设寄存器,使用的指令都是一样的

      LDR:Load Register;LDM:Load Multiple Register STR:Store Register;STM:Store Multiple Register

    • LDR与STR指令格式:

      • image.png
      • image.png
      • 注意type,B表示字节,H表示半字(16bit)
    • image.png
    • LDR/STR是访问单个地址的指令,一次只访问内存的一个地址,一次可以写入/取得一个字长的数据
    • LDM/STM指令,一次可以访问多个数据
      • image.png
      • 可以一次读取/写入多个register(reglist)
      • Rn表示地址,LDM读取多个数据保存在reglist中,读取数据存放在对应reg中后Rn地址怎么变化?
        • 地址是变大/变小? 地址是读之前变化还是读之后变化?
        • 这就是addr_mode要表述的事
      • Rn也是一个寄存器register,其中存放的是地址;所以STM/LDM只支持寄存器寻址方式
    • image.png
    • reglist中的寄存器和地址怎么对应?
      • 低标号的register对应低地址
    • image.png
    • 根据LDM/STM的4中地址变化模式,实际中栈也就可以划分为4种

      根据栈指针指向,可分为满(Full)/空(Empty):

      1. SP指向最后一个入栈的数据,需要先修改SP再入栈
      2. SP指向下一个空位置,先入栈再修改SP

      根据压栈时SP的增长方向,可分为增/减:

      1. 增(Ascending):SP变大
    1. 减(Descending):SP变小

    组合后,就有4种方式:

    满增、满减,

    空增,空减。

    • 常用的是Full_Descending的栈,SP(R13)指针指向最后一个入栈的数据并且SP指针向下生长
    • 所以对于Full_Descending的栈,压栈和出栈的操作就是:

      入栈时用STMDB,也可以用STMFD,作用一样;(压栈时先减小地址,再将数据写入地址中)

    出栈时用LDMIA,也可以用LDMFD,作用一样。(出栈时先读取数据,再将地址增加)

    • image.png
    • image.png
    • MOV指令只能在寄存器之间移动数据,或者把立即数移动到寄存器中