- 之前说过,ARM CPU访问内存或者外设寄存器都是一样的
对于编写的程序来说,无论是访问内存还是访问外设寄存器,使用的指令都是一样的
LDR:Load Register;LDM:Load Multiple Register STR:Store Register;STM:Store Multiple Register
LDR与STR指令格式:
- 注意type,B表示字节,H表示半字(16bit)
- LDR/STR是访问单个地址的指令,一次只访问内存的一个地址,一次可以写入/取得一个字长的数据
- LDM/STM指令,一次可以访问多个数据
- 可以一次读取/写入多个register(reglist)
- Rn表示地址,LDM读取多个数据保存在reglist中,读取数据存放在对应reg中后Rn地址怎么变化?
- 地址是变大/变小? 地址是读之前变化还是读之后变化?
- 这就是addr_mode要表述的事
- Rn也是一个寄存器register,其中存放的是地址;所以STM/LDM只支持寄存器寻址方式
- reglist中的寄存器和地址怎么对应?
- 低标号的register对应低地址
- 根据LDM/STM的4中地址变化模式,实际中栈也就可以划分为4种
根据栈指针指向,可分为满(Full)/空(Empty):
满SP指向最后一个入栈的数据,需要先修改SP再入栈
空SP指向下一个空位置,先入栈再修改SP
根据压栈时SP的增长方向,可分为增/减:
增(Ascending):SP变大
减(Descending):SP变小
组合后,就有4种方式:
满增、满减,
空增,空减。
- 常用的是Full_Descending的栈,SP(R13)指针指向最后一个入栈的数据并且SP指针向下生长
- 所以对于Full_Descending的栈,压栈和出栈的操作就是:
入栈时用STMDB,也可以用STMFD,作用一样;(压栈时先减小地址,再将数据写入地址中)
出栈时用LDMIA,也可以用LDMFD,作用一样。(出栈时先读取数据,再将地址增加)
- MOV指令只能在寄存器之间移动数据,或者把立即数移动到寄存器中