|
ARM指令中有2条指令MSR和MRS,用于在状态寄存器和通用寄存器之间传送数据。修改状态寄存器一般是通过“读取-修改-写回”3个步骤的操作来实现的。需要注意的是,不能通过该指令直接进行修改CPSR中的T控制位直接将程序状态切换到Thumb状态,必须通过BX等指令来完成程序状态的切换。
1. 状态寄存器到通用寄存器的传送指令MRS
MRS指令用于将状态寄存器的内容传到通用寄存器中,它主要用于以下3种场合:
通过“读取-修改-写回”操作序列修改状态寄存器的内容。MRS指令用于将状态寄存器的内容读到通用寄存器中。
当异常中断允许嵌套时,需要在进入异常中断之后、嵌套中断发生之前保存当前处理器模式对应的SPSR。这时需要先通过MRS指令读出SPSR的值,再用其他指令将SPSR值保存起来。
当进程切换时,也需要保存当前寄存器值。
二进制编码
状态寄存器向通用寄存器传送指令的二进制编码如图
说明
图中的R位用来区分是将CPSR还是当前模式的SPSR拷贝到目的寄存器,全部32位都被拷贝。MRS和MSR配合使用,作为更新PSR的“读取-修改-写回”序列的一部分。
汇编格式
MRS{<cond>} Rd,CPSR|SPSR
举例
MRS R0,CPSR ;将CPSR传送到R0
MRS R3,SPSR ;将SPSR传送到R3
注意事项
在用户或系统模式下没有可访问的SPSR,所以SPSR形式在这些模式下不能用。
当修改CPSR或SPSR时,必须注意保存所有未使用位的值,这将使这些位在将来使用时兼容的可能性最大。使用这两条指令将状态寄存器传送到一般寄存器,只修改必要的位,再将结果传送到状态寄存器,这样做可以最好地完成对CPSR或SPSR的修改。
这条指令不影响条件标志码。
2.通用寄存器到状态寄存器的传送指令MSR
当需要保存或修改当前模式下CPSR或SPSR的内容时,这些内容首先必须传送到通用寄存器中,对选择的位进行修改,然后将数据回写到状态寄存器。这里讲述的指令完成这一过程的最后一步,即用立即数常量或通用寄存器的内容加载CPSR或SPSR的指定区域。
说明
图中的操作数,可以是一个寄存器,也可以是循环移位的8位有效立即数(指定的方式与数据处理指令中第2操作数的立即数相同),在域屏蔽控制下传送到CPSR或当前模式的SPSR.
域屏蔽控制PSR寄存器内4字节的更新。指令的第16位决定PSR[7:0]是否更新,第17位控制PSR[15:8],第18位控制PSR[23:16],第19位控制PSR[31:24]。
当使用立即数操作数时,只有标志位(PSR[31:24])可选择更新。
MRS和MSR配合使用,作为更新PSR的“读写-修改-写回”序列的一部分。
汇编格式
MSR{<cond>} CPSR_f|SPSR_f,#<32-bit immediate>
MSR{<cond>}
CPSR_<field>|SPSR_<field>,Rm
这里<field>表示下列情况之一:
C——控制域,即PSR[7:0]
X——扩展域,即PSR[15:8](在当前ARM中未使用)
S——状态域,即PSR[23:16](在当前ARM中未使用)
F——标志位域,即PSR[31:24]
举例
设置N、Z、C和V标志位:
MSR CPSR_f,#&F0000000 ;设置所有标志位
仅设置C标志位,保存N、Z和V:
MSR R0,CPSR ;将CPSR传送到R0
ORR R0,R0,#&20000000 ;设置R0的29位
MSR CPSR_f,R0 ;传送回CPSR
从监控模式切换到IRQ模式(例如,启动时初始化IRQ堆栈指针):
MRS R0,CPSR ;将CPSR传送到R0
BIC R0,R0,#&
ORR R0,R0,#&12 ;设置位为IRQ模式
MSR CPSR_c,R0 ;传送回CPSR
在这种情况下,须拷贝原来CPSR的值,以便不改变中断使能设置。上面的代码可用来在任何两个非用户模式之间或从非用户模式到用户模式的切换。只有在MSR完成后,模式的改变才起作用;在将结果拷贝回CPSR之前,中间的工作对模式没有影响。
注意事项
在用户模式下不能对CPSR[23:0]做任何修改。
因为在用户或系统模式下没有CPSR,所以应尽量避免在这些模式下访问SPSR。
在嵌套的异常中断处理中,当退出中断处理程序时,通常通过MSR指令将实现保存了的保存程序状态寄存器内容恢复到当前程序状态寄存器中。
在修改的状态寄存器位域中包括未分配的位时,避免使用立即数方式的MSR指令。
凌阳教育,专注嵌入式人才培养多年,完善的培养方案,强大的师资,合理的课程安排,成功从小白蜕变为嵌入式工程师。想了解凌阳教育,或者获得更多嵌入式学习资料的免费下载,请点击www.sunplusedu.com访问凌阳教育官网