ARM指令集提供了两条指令,可直接控制程序状态寄存器(PSR,Program State Register)。MRS指令用于把CPSR或SPSR的值传送到一个寄存器;MSR与之相反,把一个寄存器的内容传送到CPSR或SPSR。这两条指令结合,可用于对CPSR和SPSR进行读/写操作。
cpsr_c代表的是这32位中的低8位,也就是控制位
CPSR有4个8位区域:标志域(F)、状态域(S)、扩展域(X)、控制域(C)
通过一般示例如下观察PSR指令的相关操作:
area myarea,code,readonly
code32
entry
vector ;创建异常向量表
b reset
nop
b swi_handler
nop
nop
b irq_handler
nop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; mrs msr
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
reset
;初始化栈
ldr r5, =0x40002000
mov sp, r5
sub r5, r5, #0x2000 ;预留8K可作为SVC模式栈空间
;切换到IRQ模式 ;注意:在user模式没有修改cpsr_c域的权限
mrs r0, cpsr
bic r0, r0, #0x1f ;清mode模式控制位,使得初始化0~4位为00000
orr r0, r0, #0x12 ;获得IRQ的模式即为 10010
msr cpsr_c, r0 ;当切换到IRQ模式时SP栈会清空,此时要重新分配栈空间
;初始化IRQ的栈空间
mov sp, r5
sub r5, r5, #0x1000 ;预留4k作为irq模式的栈空间
;开irq中断
;注意:开中断和切换模式不可以同时进行他们都在 CPSR_C的 控制域
mrs r0, cpsr ;r0 = cpsr 表示把状态寄存器的值保存在R0寄存器中
bic r0, r0, #0x080 ;I在c控制域的第七位1000-0000 清零的到 I =0
msr cpsr_c, r0 ;cpsr_c = r0
;切换到USER模式
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0x10
msr cpsr_c, r0
;初始化USER模式的栈空间
mov sp, r5
sub r5, r5, #0x1000 ;预留4k作为irq模式的栈空间
;运行用户应用
user_loop
mov r0, #00
mov r1, #0x11
mov r2, #0x22
;软中断
swi 0x5 ;open
swi 0x6 ;close
irq_handler
stmfd sp!, {r0-r12, lr}
ldmfd sp!, {r0-r12, pc}
swi_handler
stmfd sp!, {r0-r12, lr} ;保存现场
ldr r0, [lr,#-4] ;获取swi 指令的机器码
bic r0, r0, #0xff000000 ;获取swi no
cmp r0, #0x5
bleq sys_open
cmp r0, #0x6
bleq sys_close
ldmfd sp!, {r0-r12, pc}^ ;出栈 同时恢复cpsr (cpsr = spsr_
)
sys_open
stmfd sp!, {r0-r12, lr}
ldmfd sp!, {r0-r12, pc}
sys_close
stmfd sp!, {r0-r12, lr}
ldmfd sp!, {r0-r12, pc}
end
1 》 【切换到IRQ模式】
2 》【开IRQ中断】
3 》【切换到用户模式执行应用】