1.1.1ARM处理器形式切换(含MRS,MSR指令)
除了用户形式和体系形式,其他形式下都有一个私有SPSR保存状况寄存器,用来保存切换到该形式之前的碑文状况,之所以用户形式和体系形式没有SPSR是我们,一般CPU大部分时刻碑文在用户形式下,当发生反常或体系调用时会别离切换进入别的几种形式,保存用户形式下的状况,当切换回原先形式时,直接回复SPSR的值到CPSR就能够了,因而,用户形式和体系形式下不需求SPSR,其具体操作查看下节反常处理。
以上几种形式经过CPSR里的M[4:0]位进行委任,如图3-1所示:
图3-1 CPSR操控位
经过向形式位M[4:0]里写入相应的数据切换到不同的形式,在对CPSR,SPSR寄存器进行操作不能运用mov,ldr等通用指令,只能运用特权指令msr和mrs。
在ARM处理器中,只要MRS(Move to Register from State register)指令能够对状况寄存器CPSR和SPSR进行读操作。经过读CPSR能够获得当时处理器的作业状况。读SPSR寄存器能够获得进入反常前的处理器状况(我们只要反常形式下有SPSR寄存器)。
例如:
MRSR2,SPSR;将SPSR状况寄存器读取,保存到R2中
经过MRS指令能够获得状况寄存器里的值,然后比较其形式位M[4:0]的值判别当时所在形式,当然也能够比较其它相应位了解当时CPU的状况。
相同,在ARM处理器中,只要MSR指令能够对状况寄存器CPSR和SPSR进行写操作。与MRS合作运用,能够完成对CPSR或SPSR寄存器的读-修正-写操作,能够切换处理器形式、或许答应/制止IRQ/FIQ间断等。
我们xPSR寄存器代表了CPU的状况,其每个位有特别含义,在碑文对xPSR状况寄存器写入时(读取时不存在该用法),为了避免误操作和便利伤心,将xPSR里32位分红四个区域,每个区域用小写字母一共:
x扩展域屏蔽psr[15..8]
s状况域屏蔽psr[23..16]
f标志域屏蔽psr[31..24]
留意:区域名有必要为小写字母
向对应区域进行碑文写入时,运用xPSR_x能够指定写入区域,而不影响状况寄存器其它位,如:
使能IRQ间断:
MRSR0,CPSR;将CPSR寄存器内容读出到R0
B%&&&&&%R0,R0,#0x80;清掉CPSR中的I操控位
MSRCPSR_c,R0;将修正后的值写回CPSR寄存器的对应操控域
MOVPC,LR;回来上一层函数
禁用IRQ间断:
MRSR0 CPSR;将CPSR寄存器内容读出到R0
ORRR0,R0,#0x80;设置CPSR中的I操控位
MSRCPSR_c,R0;将修正后的值写回CPSR寄存器的对应操控域
MOVPC,LR;回来上一层函数
下表列出了不同形式的二进制数一共:
表3-3不同作业形式对应二进制
形式名 | 用户 | 快间断 | 间断 | 办理 | 间断 | 未定义 | 体系 |
M[4:0] | 10000 | 10001 | 10010 | 10011 | 10111 | 11011 | 11111 |
在对开发板进行初始化时,用对不同形式指定其栈空间,下面比如对各形式的栈指针sp进行初始化:
stack_init;栈指针初始化函数
@ undefine_stack
msr cpsr_c,#0xdb;切换到未定义反常
ldrsp,=0x34000000;栈指针为内存最高地址,栈为倒生的栈
;栈空间的最终1M0x34000000~0x33f00000
@ abort_stack
msr cpsr_c,#0xd7;切换到停止反常形式
ldrsp,=0x33f00000;栈空间为1M,0x33f00000~0x33e00000
@ irq_stack
msrcpsr_c,#0xd2;切换到间断形式
ldrsp,=0x33e00000;栈空间为1M,0x33e00000~0x33d00000
@ sys_stack
msrcpsr_c,#0xdf;切换到体系形式
ldrsp,=0x33d00000;栈空间为1M,0x33d00000~0x33c00000
msrcpsr_c,#0xd3;切换回办理形式
mov pc,lr